Manchmal sehe ich den folgenden Befehl:
find . -name * -exec ls -a {} \;
Ich wurde gebeten, dies auszuführen.
Was {} \;
heißt hier?
command-line
find
codeofnode
quelle
quelle
-name *
ist überflüssig.-name *
ist schlimmer als überflüssig. Da das*
nicht in Anführungszeichen gesetzt ist, erweitert die Shell es auf die Liste der Dateinamen im aktuellen Ordner, wobei Leerzeichen falsch behandelt werden, was zu unerwarteten Ergebnissen oder einer Fehlermeldung führt. Als zusätzlichen Punktfind
hat viele Funktionen, von denen eine darin besteht, Dateien aufzulisten; Dies vermeidet die Verwendung-exec
. ZB können Siefind . -print
oder verwendenfind . -ls
. Schließlich gibt es zwei Möglichkeiten , die Semikolons zu entkommen: entweder , wie Sie mit dem Backslash haben,\;
oder mit einem Zitat:';'
. Verwenden Sie, womit Sie sich wohler fühlen.Antworten:
Wenn Sie laufen
find
mitexec
,{}
erweitert auf die Dateinamen jede Datei oder das Verzeichnis gefunden mitfind
(so dassls
in Ihrem Beispiel jeden gefundenen Dateinamen als Argument bekommt - zur Kenntnis , dass es nenntls
oder was auch immer anderer Befehl , den Sie angeben , einmal für jede Datei gefunden).Semikolon
;
beendet den Befehl, der von ausgeführt wirdexec
. Es muss mit einem Escapezeichen versehen werden,\
damit die Shell, die Sie ausführen,find
es nicht als ihren eigenen besonderen Charakter behandelt, sondern es an weitergibtfind
.In diesem Artikel finden Sie weitere Informationen.
Außerdem
find
bietet einige Optimierungen mitexec cmd {} +
- wenn so läuft,find
Appends Dateien an das Ende des Befehls gefunden , anstatt sie einmal pro Datei aufgerufen wird (so dass der Befehl nur einmal ausgeführt wird, wenn möglich).Der Unterschied im Verhalten (wenn nicht in der Effizienz) ist leicht erkennbar, wenn mit
ls
zAngenommen, Sie haben einige
jpg
Dateien (mit ausreichend kurzen Pfaden ), ist das Ergebnis eine Zeile pro Datei im ersten Fall und das Standardverhaltenls
bei der Anzeige von Dateien in Spalten für letztere.quelle
\;
mit+
.find . -name * | ls -a -
?find
. Außerdemls
hängt die Ausgabe von in diesem Fall anscheinend nicht von der Eingabe ab - egal, was ich als Filter verwendefind
, es wirdls
nur der Inhalt des Arbeitsverzeichnisses angezeigt, und das ist alles. Überprüfen Sie zum Beispielfind ~ -iname '*.jpg' -exec ls -a {} \;
vsfind ~ -iname '*.jpg' | ls -a
.echo 'foo' | ls -a
.-
in Ihremls -a -
Befehl verpasst, als Sie getestet haben, was @ dr-h abgefragt hat.Von der Manpage für den
find
Befehl :Also hier ist die Erklärung:
{}
bedeutet "die Ausgabe vonfind
". Wie in "wasfind
auch immer gefunden".find
gibt den Pfad der gesuchten Datei zurück, oder? So{}
ersetzt es; Es ist ein Platzhalter für jede Datei, die derfind
Befehl findet (von hier genommen ).Der
\;
Teil sagt im Grundefind
"okay, ich bin fertig mit dem Befehl, den ich ausführen wollte".Beispiel:
Nehmen wir an, ich befinde mich in einem Verzeichnis voller
.txt
Dateien. Ich laufe dann:Der erste Teil
find . -name *.txt
gibt eine Liste der.txt
Dateien zurück. Der zweite Teil,-exec cat {} \;
wird dencat
Ausführungsbefehl für jede durch gefundene Dateifind
, socat file1.txt
,cat file2.txt
und so weiter.quelle
*.txt
muss mit angegeben werden'*.txt'
. Dies liegt daran, dass, wenn sich.txt
Dateien im aktuellen Ordner befinden, die Shell dies erweitert und Sie falsche Ergebnisse oder eine Fehlermeldung erhalten.find -name '*.txt' -exec cat {} \;