Path
將路徑規範分解為最長公共前綴 + 後綴
給定任意兩個絕對 Unix 路徑規範1,可以將每個規範分解為最長公共前綴和特定後綴的串聯。例如,
/abc/bcd/cdf -> /abc/bcd + cdf /abc/bcd/chi/hij -> /abc/bcd + chi/hij
是否有 Unix 實用程序(或實用程序)來計算這種分解?(我添加了“或實用程序”,以防有單獨的實用程序用於計算最長公共前綴和計算相對路徑。)
(我意識到編寫這樣的實用程序並不是非常困難,但我盡量優先考慮那些或多或少標準的工具,而不是定制的工具。)
1我寫“路徑規範”而不是“路徑”來迴避諸如給定文件系統中存在(路徑)、連結等問題。
您可以在 shell 循環中執行此操作。下面的程式碼應該適用於各種帶有額外斜杠的奇怪路徑;如果你所有的路徑都是這種形式
/foo/bar
,你可以用更簡單的東西逃脫。split_common_prefix () { path1=$1 path2=$2 common_prefix= ## Handle initial // specially case $path1 in //[!/]*) case $path2 in //[!/]*) common_prefix=/ path1=${path1#/} path2=${path2#/};; *) return;; esac;; /*) case $path2 in /*) :;; *) return;; esac;; *) case $path2 in /*) return;; esac;; esac ## Normalize multiple slashes trailing_slash1= trailing_slash2= case $path1 in */) trailing_slash1=/;; esac case $path2 in */) trailing_slash2=/;; esac path1=$(printf %s/ "$path1" | tr -s / /) path2=$(printf %s/ "$path2" | tr -s / /) if [ -z "$trailing_slash1" ]; then path1=${path1%/}; fi if [ -z "$trailing_slash2" ]; then path2=${path2%/}; fi ## Handle the complete prefix case (faster, necessary for equality and ## for some cases with trailing slashes) case $path1 in "$path2") common_prefix=$path1; path1= path2= return;; "$path2"/*) common_prefix=$path2; path1=${path1#$common_prefix} path2= return;; esac case $path2 in "$path1"/*) common_prefix=$path1; path1= path2=${path2#$common_prefix} return;; esac ## Handle the generic case while prefix1=${path1%%/*} prefix2=${path2%%/*} [ "$prefix1" = "$prefix2" ] do common_prefix=$common_prefix$prefix1/ path1=${path1#$prefix1/} path2=${path2#$prefix1/} done }
或者,確定兩個字元串中最長的公共前綴並將其修剪到最後一個
/
字元(公共前綴僅由斜杠組成時除外)。
您可以使用以下方法計算行列表的最長公共前導子字元串:
sed -e '1{h;d;}' -e 'G;s,\(.*\).*\n\1.*,\1,;h;$!d'
例如:
/abc/bcd/cdf /abc/bcd/cdf/foo /abc/bcd/chi/hij /abc/bcd/cdd
返回:
/abc/bcd/c
要將其限制為路徑組件:
sed -e 's,$,/,;1{h;d;}' -e 'G;s,\(.*/\).*\n\1.*,\1,;h;$!d;s,/$,,'
(返回
/abc/bcd
上面的範例)。