たとえば、パスを持つ変数がありrelease/linux/x86
、別のディレクトリ (つまり、../../..
現在の作業ディレクトリ) からの相対パスが必要な場合、シェル コマンド (または GNU Make) でそれを取得するにはどうすればよいですか?
ソフトリンクのサポートは必要ありません。
この質問は、用語の改善のため、承認された回答に基づいて大幅に変更されました。
答え1
目的が全く分かりませんが、これはまさに求められていることを実行します。GNU リアルパス:
realpath -m --relative-to=release/linux/x86 .
../../..
realpath -m --relative-to=release///./linux/./x86// .
../../..
答え2
これは、ディスクやネットワークにアクセスせずに、シェルパラメータの拡張を通じて文字列操作のみを使用してソースディレクトリからターゲットディレクトリへの相対パスを返すシェル関数です。パス名はありません 解決 終わらせる。
2 つのパラメータ、source-dir と target-dir が必要です。どちらも絶対正規化された空でないパス名で、どちらかが - で終わる場合があり、どちらも存在する必要がありません。void の場合は、末尾の なしで、source-dir から target-dir への相対パスとして/
結果をシェル変数に返します。$REPLY
/
.
アルゴリズムは2005年のcomp.unix.shellの投稿から引用したもので、現在はアーカイブ。
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}
または、URI共有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:-.}"
}
(更新終了)