Die Antwort von muru ist angemessen und gut geeignet für Fälle, in denen wir etwas drucken möchten, wenn eine Datei gefunden wird. Für den allgemeinen Fall, wenn wir einen externen Befehl ausführen möchten, z. B. echo
könnten wir -exec
flag verwenden.
$ find . -name 'xac' -exec echo "I found " {} \; -quit
I found ./xac
Der {}
Teil übergibt den Dateinamen an den Befehl zwischen -exec
und \;
als Argumente. Beachten Sie das \
Vorherige ;
- es verhindert, dass die Shell es falsch interpretiert. ; Im Semikolon zum Schließen der Shell bedeutet das Ende des Befehls. Wenn es jedoch mit einem Schrägstrich versehen wird, behandelt die Shell es als Literall-Text, der an den find
Befehl übergeben wird, und um den Befehl zu finden, dient es als -exec
Argument für das Schließen des Flags.
Für die Erstellung von Bedingungen dieser if found do this; else do that
Art könnten wir Befehlssubstitution $()
und test
Befehl (aka [
) verwenden:
$ [ "x$(find . -name 'noexist' -print -quit)" != "x" ] && echo "found" || echo "not found"
not found
$ [ "x$(find . -name 'xac' -print -quit)" != "x" ] && echo "found" || echo "not found"
found
Adressierung von Dans Kommentar
Dan fragte in den Kommentaren :
Wäre das Echo "Ich habe {} gefunden" nicht besser als das Echo "Ich habe gefunden" {}? Vielleicht ist es für Echo in Ordnung, aber wenn jemand den Befehl kopiert und das Echo durch einen anderen Befehl ersetzt, hat er möglicherweise ein Problem
Lassen Sie uns zuerst das Problem verstehen. Normalerweise gibt es in Shells das Konzept der Wortteilung, was bedeutet, dass nicht zitierte Variablen und Positionsparameter erweitert und als separate Elemente behandelt werden. Wenn Sie Variable Zum Beispiel haben var
und es enthält hello world
Text, wenn Sie tun , touch $var
die Schale wird es brechen in zwei separate Elemente hello
und world
und touch
wird das verstehen , als ob Sie versuchen , zwei separate Dateien zu erstellen; Wenn Sie dies tun touch "$var"
, wird die Shell hello world
als eine Einheit behandelt und touch
nur eine Datei erstellt. Dies ist wichtig zu verstehen, dass dies nur aufgrund der Funktionsweise von Muscheln geschieht.
Im Gegensatz dazu find
leidet es nicht unter einem solchen Verhalten, da Befehle von find
selbst verarbeitet und per execvp()
Systemaufruf ausgeführt werden , sodass keine Shell beteiligt ist. Während geschweifte Klammern in Muscheln eine besondere Bedeutung haben, weil sie in der Mitte des find
Befehls und nicht am Anfang erscheinen, haben sie in diesem Fall keine besondere Bedeutung für Muscheln. Hier ist ein Beispiel. Lassen Sie uns ein paar schwierige Dateinamen erstellen und versuchen, sie als Argument an den stat
Befehl zu übergeben.
$ touch with$'\t'tab.txt with$' 'space.txt with$'\n'newline.txt
$ find -type f -exec stat -c "%F" {} \; -print
regular empty file
./with?newline.txt
regular empty file
./with space.txt
regular empty file
./with?tab.txt
Wie Sie sehen können, werden stat
schwierige Dateinamen problemlos verwendet. Dies find
ist einer der Hauptgründe, warum dies für die Verwendung in tragbaren Skripten empfohlen wird. Dies ist besonders nützlich, wenn Sie den Verzeichnisbaum durchlaufen und möglicherweise mit Dateinamen arbeiten möchten, die möglicherweise vorhanden sind Sonderzeichen in ihnen. Daher ist es nicht erforderlich, geschweifte Klammern für Befehle anzugeben, die in ausgeführt werden find
.
Es ist eine andere Geschichte, wenn Shell beteiligt wird. Manchmal müssen Sie eine Shell verwenden, um den Dateinamen zu verarbeiten. In diesem Fall ist das Zitieren zwar wichtig, aber es ist wichtig zu erkennen, dass es nicht das Problem von find ist - es ist die Shell, die die Wortteilung durchführt.
$ find -type f -exec bash -c "stat {}" sh \;
stat: cannot stat './with': No such file or directory
sh: line 1: newline.txt: command not found
stat: cannot stat './with': No such file or directory
stat: cannot stat 'space.txt': No such file or directory
stat: cannot stat './with': No such file or directory
stat: cannot stat 'tab.txt': No such file or directory
Wenn wir also innerhalb der Shell zitieren , wird es funktionieren. Aber auch das ist wichtig für Shell, nicht find
.
$ find -type f -exec bash -c "stat -c '%F' '{}'" sh \;
regular empty file
regular empty file
regular empty file
/some/path
sagt find, wo man anfangen soll zu suchen, aber nichts sagt ihm, wonach er suchen soll. Gleiches gilt für Ihre verknüpfte Antwort. Was für mich funktioniert, istfind /some/path -name xac -print0 -quit | grep -qz . && echo found
. Habe ich etwas verpasst?