¿Cómo calcular una ruta relativa a partir de dos rutas absolutas en el shell de Linux?

17

Tenemos dos caminos. El primero es el directorio, el segundo es un directorio o un archivo.

/a/b/c y /a/d/e.txt

La ruta relativa de la primera a la segunda será:

../../d/e.txt

¿Cómo calcular eso en la terminal de Linux? Para aquellos que preguntan "¿Qué es el caso de uso?", Se podría usar esto, por ejemplo, para crear muchos enlaces simbólicos relativos.

techraf
fuente
1
Esto no debería haber sido migrado.
1
Debería haberse cerrado como un duplicado.
Pausado hasta nuevo aviso.

Respuestas:

10

Suponiendo GNU coreutils:

  • Para enlaces simbólicos, lnrecientemente aprendió la --relativeopción.

  • Para todo lo demás, realpathadmite opciones --relative-to=y --relative-base=.

usuario1686
fuente
1
¿Cómo lo haces con BusyBox?
DUzun
4

Para mí, esta respuesta (que usa un oneliner de python) funciona perfectamente.

$ python -c "import os.path; print os.path.relpath('/a/d/e.txt', '/a/b/c')"
../../d/e.txt

Probado con éxito en Linux (Kubuntu 14.04) y en Mac OSX, necesita Python 2.6.

Joe
fuente
2

Para no depender de realpatheso no está constantemente disponible y minimizar las dependencias, se me ocurrió esto (usando un poco de ayuda de esta respuesta ):

function relative_path_from_to() {
  # strip trailing slashes
  path1=${1%\/}
  path2=${2%\/}
  # common part of both paths
  common=$(printf '%s\x0%s' "${path1}" "${path2}" | sed 's/\(.*\).*\x0\1.*/\1/')
  # how many directories we have to go up to the common part
  up=$(grep -o "/" <<< ${path1#$common} | wc -l)
  # create a prefix in the form of ../../ ...
  prefix=""; for ((i=0; i<=$up; i++)); do prefix="$prefix../"; done
  # return prefix plus second path without common
  printf "$prefix${2#$common}"
}

Genera una subshell para encontrar la parte común de ambas rutas. Tal vez te guste, funciona para mí.

Pascal
fuente