Comment calculer un chemin relatif à partir de deux chemins absolus dans le shell Linux?


17

Nous avons deux voies. Le premier est le répertoire, le second soit un répertoire ou un fichier.

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

Le chemin relatif du premier au deuxième sera:

../../d/e.txt

Comment calculer cela dans un terminal Linux? Pour ceux qui demandent «Quel est le cas d'utilisation?», On pourrait utiliser cela, par exemple, pour créer de nombreux liens symboliques relatifs.


1
Cela n'aurait pas dû être migré.

1
Il aurait dû être fermé en double.
pause jusqu'à nouvel ordre.

Réponses:


10

En supposant que GNU coreutils:

  • Pour les liens symboliques, ln a récemment appris l' --relativeoption.

  • Pour tout le reste, realpathprend en charge les options --relative-to=et --relative-base=.


1
Comment faites-vous avec BusyBox?
DUzun

4

Pour moi, cette réponse (qui utilise un oneliner en python) fonctionne parfaitement.

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

Testé avec succès sur Linux (Kubuntu 14.04) et sur Mac OSX, nécessite Python 2.6.


2

Pour ne pas dépendre de ce realpathqui n'est pas toujours disponible et minimiser les dépendances, j'ai trouvé cela (en utilisant un peu d'aide de cette réponse ):

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}"
}

Génère un sous-shell pour trouver la partie commune des deux chemins. Peut-être que vous l'aimez - fonctionne pour moi.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.