通常,長路徑會被錯誤輸入,或者您會收到一條路徑不存在的日誌檔案條目。是否有命令或 shell 函數可以導航路徑層次結構,直到找到匹配的路徑?
命令列交換可以像這樣:
$ ls /var/lib/my/supper/complicated/path
File or directory not found
$ fixpath /var/lib/my/supper/complicated/path
Found /var/lib/my
作為一個獎勵功能,相似性檢測會很棒:
$ fixpath /var/lib/my/supper/complicated/path
Found /var/lib/my
Did you mean /var/lib/my/super/complicated/path
答案1
$ fixpath /home/user/docus/collection/unix/djakl/jfkdsl/dfjksld/fsdkl
Found /home/user/docus/collection/unix
$ type fixpath
fixpath is a function
fixpath ()
{
CURDIR="$PWD";
DIR="$1";
E=1;
while [ $E -eq 1 ]; do
cd "$DIR" 2> /dev/null && {
E=0;
echo Found "$DIR"
} || {
DIR="${DIR%/*}";
DIR="${DIR:-/}"
};
done;
cd "$CURDIR"
}
大多數現代 shell 都可以自行進行相似性自動修正。至少 bash 和 zsh 是這樣。
答案2
以下 shell 函數採用路徑名並確定實際存在的最長位元。它透過從路徑中刪除最後一個路徑元素來實現此目的,直到路徑完全為空,或者它對應於實際存在的檔案(或目錄或任何內容)。
fixpath () (
pathname="$1"
while [ -n "$pathname" ] && [ ! -e "$pathname" ]; do
pathname=${pathname%/*}
case "$pathname" in
*/*) continue ;;
*) [ -e "$pathname" ] || pathname=''
break
esac
done
printf 'Longest existing path in "%s" is "%s"\n' "$1" "$pathname"
)
在不包含 a 的情況下需要該case
語句來終止迴圈(這表示它不會被變數取代修改)。這可以避免某些情況下的無限循環。$pathname
/
測試它:
$ fixpath /home/kk/blaha/123
Longest existing path in "/home/kk/blaha/123" is "/home/kk"
$ fixpath "$HOME/.profile"
Longest existing path in "/home/kk/.profile" is "/home/kk/.profile"
$ fixpath "n"
Longest existing path in "n" is ""