Es kommt häufig vor, dass ein langer Pfad falsch eingegeben wird oder Sie einen Protokolldateieintrag erhalten, dass ein Pfad nicht existiert. Gibt es einen Befehl oder eine Shell-Funktion, die durch die Pfadhierarchie navigiert, bis sie einen passenden Pfad findet?
Der Befehlszeilenaustausch könnte folgendermaßen ablaufen:
$ ls /var/lib/my/supper/complicated/path
File or directory not found
$ fixpath /var/lib/my/supper/complicated/path
Found /var/lib/my
Als Bonus-Feature wäre eine Ähnlichkeitserkennung toll:
$ fixpath /var/lib/my/supper/complicated/path
Found /var/lib/my
Did you mean /var/lib/my/super/complicated/path
Antwort1
$ 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"
}
Die Ähnlichkeits-Autokorrektur können die meisten modernen Shells selbst durchführen. Zumindest Bash und Zsh können das.
Antwort2
Die folgende Shell-Funktion nimmt einen Pfadnamen und ermittelt das längste Stück davon, das tatsächlich existiert. Dies geschieht, indem das letzte Pfadelement aus dem Pfad entfernt wird, bis der Pfad entweder vollständig leer ist oder einer Datei (oder einem Verzeichnis oder irgendetwas) entspricht, die tatsächlich existiert.
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"
)
Die case
Anweisung wird benötigt, um die Schleife zu beenden, wenn $pathname
kein a enthalten ist /
(was bedeutet, dass es durch die Variablensubstitution nicht verändert würde). Dadurch wird unter Umständen eine Endlosschleife vermieden.
Testen:
$ 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 ""