Как рассчитать относительный путь из двух абсолютных путей в оболочке Linux?

17

У нас есть два пути. Первый - это каталог, второй - каталог или файл.

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

Относительный путь от первого пути ко второму будет:

../../d/e.txt

Как рассчитать это в терминале Linux? Для тех, кто спрашивает «Что такое вариант использования?», Можно использовать это, например, для создания множества относительных символических ссылок.

techraf
источник
1
Это не должно быть перенесено.
1
Он должен был быть закрыт как дубликат.
Приостановлено до дальнейшего уведомления.

Ответы:

10

Предполагая, что GNU coreutils:

  • Для символических ссылок lnнедавно узнал --relativeопцию.

  • Для всего остального, realpathподдерживает параметры --relative-to=и --relative-base=.

user1686
источник
1
Как вы делаете это с BusyBox?
Дзузун
4

Для меня этот ответ (который использует python oneliner) работает идеально.

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

Успешно протестирован на Linux (Kubuntu 14.04) и на Mac OSX, требуется Python 2.6.

Джо
источник
2

Чтобы не зависеть от того, realpathчто не всегда доступно, и минимизировать зависимости, я придумал это (используя небольшую справку из этого ответа ):

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

Создает подоболочку для нахождения общей части обоих путей. Может быть, вам это нравится - работает для меня.

паскаль
источник