Me gustaría convertir una ruta de archivo absoluta en relativa a partir de otra ruta absoluta dada. Algo así:
absoluta="/foo/bar" origen="/foo/baz/foo" # magia bash ... relativa="../../bar"
¿Alguien sabe cómo crear esa magia bash para que el script convierta las rutas absolutas en relativas?
Estás leyendo una traducción autorizada de la pregunta
BASH: Convert absolute path into relative path given a current directory
planteada por Paul Tarjan
en StackOverflow.
Respuestas
Si pudieras utilizar cualquier lenguaje de programación tipo Perl/Python/PHP/Ruby, podrías solucionar este problema fácilmente en una línea de código. Pero como pides solucionarlo mediante un script de Bash, esta es el código completo que debes utilizar:
# $1 y $2 deben ser rutas absolutas que empiecen por / # el script devuelve la ruta relativa a $2/$target desde $1/$source source=$1 target=$2 common_part=$source # for now result="" # for now while [[ "${target#$common_part}" == "${target}" ]]; do # no match, means that candidate common part is not correct # go up one level (reduce common part) common_part="$(dirname $common_part)" # and record that we went back, with correct / handling if [[ -z $result ]]; then result=".." else result="../$result" fi done if [[ $common_part == "/" ]]; then # special case for root (no common path) result="$result/" fi # since we now have identified the common part, # compute the non-common part forward_part="${target#$common_part}" # and now stick all parts together if [[ -n $result ]] && [[ -n $forward_part ]]; then result="$result$forward_part" elif [[ -n $forward_part ]]; then # extra slash removal result="${forward_part:1}" fi echo $result
Y este sería el resultado de ejecutar este script con diferentes rutas:
$ calcula_ruta.sh "/A/B/C" "/A" --> "../.." $ calcula_ruta.sh "/A/B/C" "/A/B" --> ".." $ calcula_ruta.sh "/A/B/C" "/A/B/C" --> "" $ calcula_ruta.sh "/A/B/C" "/A/B/C/D" --> "D" $ calcula_ruta.sh "/A/B/C" "/A/B/C/D/E" --> "D/E" $ calcula_ruta.sh "/A/B/C" "/A/B/D" --> "../D" $ calcula_ruta.sh "/A/B/C" "/A/B/D/E" --> "../D/E" $ calcula_ruta.sh "/A/B/C" "/A/D" --> "../../D" $ calcula_ruta.sh "/A/B/C" "/A/D/E" --> "../../D/E" $ calcula_ruta.sh "/A/B/C" "/D/E/F" --> "../../../D/E/F"
@librosweb
9 octubre 2014, 18:00