長いパスが誤って入力されたり、パスが存在しないというログ ファイルのエントリが表示されたりすることがよくあります。一致するパスが見つかるまでパス階層を移動するコマンドまたはシェル関数はありますか?
コマンドラインでのやり取りは次のようになります。
$ 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"
}
類似性の自動修正は、ほとんどの最新シェルで自動的に実行できます。少なくとも bash と zsh では実行できます。
答え2
次のシェル関数はパス名を受け取り、実際に存在する最長ビットを決定します。これは、パスが完全に空になるか、実際に存在するファイル (またはディレクトリなど) に対応するまで、パスから最後のパス要素を削除することによって行われます。
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"
)
が含まれていない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 ""