Wie berechnet man einen relativen Pfad aus zwei absoluten Pfaden in der Linux-Shell?


17

Wir haben zwei Wege. Erstens ist Verzeichnis, zweitens entweder ein Verzeichnis oder eine Datei.

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

Der relative Pfad vom ersten zum zweiten Pfad ist:

../../d/e.txt

Wie berechnet man das im Linux-Terminal? Für diejenigen, die nach dem Anwendungsfall fragen, kann dies beispielsweise verwendet werden, um viele relative Symlinks zu erstellen.


1
Dies sollte nicht migriert worden sein.

1
Es sollte als Duplikat geschlossen worden sein.
Bis auf weiteres angehalten.

Antworten:


10

Angenommen, GNU-Coreutils:

  • Für Symlinks lnhat sich vor kurzem die --relativeOption angeeignet.

  • Für alles andere realpathunterstützt Optionen --relative-to=und --relative-base=.


1
Wie machst du das mit BusyBox?
DUzun,

4

Für mich funktioniert diese Antwort (die einen Python-Oneliner verwendet) perfekt.

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

Unter Linux (Kubuntu 14.04) und Mac OSX erfolgreich getestet, benötigt Python 2.6.


2

Um nicht davon abzuhängen, realpathdass dies nicht konsequent verfügbar ist und die Abhängigkeiten zu minimieren, habe ich mir das einfallen lassen (mit etwas Hilfe aus dieser Antwort ):

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

Erzeugt eine Subshell, um den gemeinsamen Teil beider Pfade zu finden. Vielleicht gefällt es dir - funktioniert bei mir.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.