如何取得兩個目錄之間的相對路徑?

如何取得兩個目錄之間的相對路徑?

假設我有一個帶有 path 的變量release/linux/x86,並且想要來自不同目錄的相對路徑(即../../..當前工作目錄),我如何在 shell 命令(或者可能是 GNU Make)中獲得它?

不需要軟連結支援。


該問題已根據改進術語的公認答案進行了大量修改。

答案1

絕對不清楚它的目的,但這將完全按照要求執行,使用GNU 實路徑

realpath -m --relative-to=release/linux/x86 .
../../..
realpath -m --relative-to=release///./linux/./x86// .
../../..

答案2

這是一個 shell 函數,它僅使用字串操作(透過 shell 參數擴展)返回從來源到目標目錄的相對路徑,無需磁碟或網路存取。無路徑名 解決 已經完成了。

需要兩個參數,source-dir 和 target-dir,都是絕對規範化的非空路徑名,兩者都可以以/- 結尾,兩者都不需要存在。如果為空,則將結果傳回 shell 變數中$REPLY,作為從來源目錄到目標目錄的相對路徑/,不帶尾隨.

演算法來自 2005 年的 comp.unix.shell 帖子,現在已升級為Archive.org

pnrelpath() {
    set -- "${1%/}/" "${2%/}/" ''               ## '/'-end to avoid mismatch
    while [ "$1" ] && [ "$2" = "${2#"$1"}" ]    ## reduce $1 to shared path
    do  set -- "${1%/?*/}/"  "$2" "../$3"       ## source/.. target ../relpath
    done
    REPLY="${3}${2#"$1"}"                       ## build result
    # unless root chomp trailing '/', replace '' with '.'
    [ "${REPLY#/}" ] && REPLY="${REPLY%/}" || REPLY="${REPLY:-.}"
}

用於

$ pnrelpath "$HOME" "$PWD"
projects/incubator/nspreon
$ pnrelpath "$PWD" "$gimpkdir"
../../../.config/GIMP
$ pnrelpath "$PWD" "$(cd "$dirnm" && pwd || false)"
# using cd to resolve, canonicalize ${dirnm}

或者,與統一資源標識符的分享scheme://authority

$ pnrelpath 'https://example.com/questions/123456/how-to' 'https://example.com/media'
../../../media

更新2022年11月24日

跳過while上一個函數中的語句將傳回以下內容realpath --relative-base:如果目標位於來源或來源之下,則傳回從來源到目標目錄的相對路徑,否則傳回絕對路徑。類似的前置條件和後置條件也適用。

pnrelbase() {
    set -- "${1%/}/" "${2%/}/"      ## '/'-end to avoid mismatch
    REPLY="${2#"$1"}"               ## build result
    # unless root chomp trailing '/', replace '' with '.'
    [ "${REPLY#/}" ] && REPLY="${REPLY%/}" || REPLY="${REPLY:-.}"
}

(更新結束)

相關內容