Ich möchte eine Datei finden und dann das Verzeichnis eingeben, das sie enthält. Ich habe es find /media/storage -name "Fedora" | xargs cd
aber natürlich versucht den is not a directory
Fehler.
Wie gebe ich das übergeordnete Verzeichnis mit einem einzeiligen Befehl ein?
shell
find
xargs
cd-command
Hrvoje T.
quelle
quelle
shopt -s globstar
könnten Siecd /media/storage/**/Fedora
, aber das hört nicht auf, den Glob beim ersten Match auszuwerten (es ist also langsamer als die Lösung von steeldriver. Für die interaktive Verwendung würde ich normalerweise nach der Maus greifen und den Verzeichnisnamen kopieren / einfügen). (und Alt + Rücktaste nach Bedarf, um nachlaufende Pfadkomponenten zu entfernen, die ich nicht wollte), aber wenn Sie dies häufig tun, könnte es sich lohnen, eine Shell-Funktion zu erstellen.xargs cd
kann ich unmöglich arbeiten.cd
kann nur als integrierte Shell arbeiten, da der Kontext der Shell selbst geändert werden muss. Einxargs
untergeordneter Prozess kann das auf keinen Fall . IDK, wenn Sie das mit "natürlich" gemeint haben oder wenn der Pfad, derfind
gedruckt wird, Leerzeichen enthält, die durch xargs geteilt werden, da Sie nichts verwendet haben-d \n
oder so. Oderfind -exec {} \;
.cd
.cd
ist ein eingebauter Bash, wenncd
ein separater Befehl wäre, würde er (sein eigenes) Verzeichnis ändern und dann beenden (Sie werden zur Shell zurückkehren, die sich im selben Zustand wie zuvor befindet, keine Änderung des Verzeichnisses).Antworten:
Zumindest wenn Sie GNU haben
find
, können-printf '%h'
Sie das Verzeichnis abrufenAlso könntest du es wahrscheinlich tun
Das
-quit
sollte verhindern, dass mehrere Argumente fürcd
den Fall, dass mehr als eine Datei übereinstimmt.quelle
-quit
wird auch nicht unbedingt unterstützt. In NetBSD heißt es-exit
, siehe unix.stackexchange.com/a/62883/117599Ähnlich wie bei der Steeldriver- Lösung, jedoch mit
-execdir
(wenn Sie diesfind
unterstützen, wie GNUs oder FreeBSDsfind
) in Kombination mitpwd
:-quit
ist optional, wenn nur ein einziges Ergebnis vorliegt und das Crawlen des gesamten Verzeichnisses kein Problem darstellt. Auf NetBSD ist es-exit
und auf OpenBSD existiert es nicht.quelle
\;
?-exec
wirdfind
das Ende der Parameter angegeben, die der Befehl ausführen soll. Da wirpwd
hier aber ohne Parameter aufrufen wollen , setzen wir das\;
Recht danach.find
Implementierungen, die execdir unterstützen, aber nicht-printf %h
? Scheint mir unwahrscheinlich. Leider wird keiner von POSIX benötigt: /find
: freebsd.org/cgi/man.cgi?find%281%29 ( Ich habe es gerade bei einer FreeBSD 11-Installation bestätigt.)-quit
/-exit
überhaupt nicht.Sie können find dazu bringen, eine neue Shell in dem gefundenen Verzeichnis auszuführen.
Danach ist das aktuelle Verzeichnis dasjenige, in dem sich eine Datei mit dem Namen Fedora befindet. ;)
Offensichtlich funktioniert dies nur dann, wenn Sie Befehle interaktiv eingeben.
quelle
Mit
zsh
:bis
cd
in das ersten (in alphabetischer Reihenfolge) Verzeichnis , das eine Datei mit dem Namen enthältFedora
.**
: jede Ebene von Verzeichnissen (versteckte Verzeichnisse werden standardmäßig weggelassen, verwenden Sie dasD
Glob-Qualifikationsmerkmal, um sie einzuschließen )[1]
: nur der erste:h
: head modifier: nimm den dirnamen.Im Gegensatz dazu
cd "$(find ...)"
funktioniert es auch, wenn der Verzeichnisname mit einem Zeilenumbruch endet. Ein weiterer Vorteil ist , dass Sie einen bekommen würden keine Übereinstimmung Fehlermeldung , wenn kein passendes Verzeichnis ist (während in den meisten Schalencd ""
würde nichts still tun).Ein Nachteil ist, dass es das ganze kriechen würde,
/media/storage
bevor es zurückkehrt.quelle
cd
bei mehreren Argumenten ohnehin nur das erste Argument angezeigt. Diescd $(dirname /media/storage/**/Fedora)
würde (mitshopt -s globstar
) funktionieren, wenn der Pfad keine Leerzeichen enthält. Um es richtig zu zitieren, denke ich, dass ein Bash-Array am einfachsten ist :target=(/media/storage/**/Fedora); cd "${target%/*}"
. Zu diesem Zeitpunkt wäre es jedoch schneller gewesen, die Suchausgabe mit der Maus zu kopieren / einzufügen, anstatt sie interaktiv zu erstellen.dirname
Implementierungen akzeptieren nicht mehr als ein Argument. Beachten Sie, dass es sich nicht um Leerzeichen handelt , sondern um Zeichen, die sich derzeit in$IFS
(Leerzeichen, Tabulatoren und Zeilenumbrüche) und Platzhalterzeichen befinden. Beachten Sie, dass , obbash
‚scd
akzeptieren mehr als ein Argument hängt davon ab , wie es kompiliert wurde (CD_COMPLAINS
inconfig-top.h
). Man kann sich vorstellen, dass zukünftige Versionen vonbash
schließlich auch die Zwei-Argumente-Funktion wie in zsh implementieren werden."${target%*/}"
sie nur auf das erste Array-Element (mit dem entfernten/Fedora
) erweitert wird. Ich denke, dass die Version gegenüber allen möglichen Zeichen im Pfadnamen völlig robust ist.