Jak obliczyć ścieżkę względną z dwóch ścieżek bezwzględnych w powłoce Linux?

17

Mamy dwie ścieżki. Pierwszy to katalog, drugi to katalog lub plik.

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

Ścieżka względna od pierwszej ścieżki do drugiej będzie:

../../d/e.txt

Jak obliczyć to w terminalu Linux? Dla tych, którzy pytają „Co to jest przypadek użycia?” Można to wykorzystać - na przykład - do stworzenia wielu względnych dowiązań symbolicznych.

techraf
źródło
1
To nie powinno być migrowane.
1
Powinien zostać zamknięty jako duplikat.
Wstrzymano do odwołania.

Odpowiedzi:

10

Zakładając, że GNU coreutils:

  • W przypadku dowiązań symbolicznych lnniedawno poznał tę --relativeopcję.

  • Do wszystkiego innego realpathobsługuje opcje --relative-to=i --relative-base=.

użytkownik1686
źródło
1
Jak to robisz z BusyBox?
DUzun
4

Dla mnie ta odpowiedź (która używa onelinera pythonowego) działa idealnie.

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

Z powodzeniem przetestowany na systemie Linux (Kubuntu 14.04) i na Mac OSX, wymaga Pythona 2.6.

Joe
źródło
2

Aby nie polegać na realpathtym, że nie jest to konsekwentnie dostępne i minimalizować zależności, wymyśliłem to (korzystając z niewielkiej pomocy z tej odpowiedzi ):

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

Odradza podpowłokę do znajdowania wspólnej części obu ścieżek. Może ci się podoba - działa dla mnie.

Pascal
źródło