如何获取两个目录之间的相对路径?

如何获取两个目录之间的相对路径?

假设我有一个带有 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:-.}"
}

(更新结束)

相关内容