Ich war verwirrt darüber, warum der findBefehl auch beschnittene Verzeichnisse druckte , und einige andere komplizierte Details darüber -prune, wie es funktionierte, konnte es aber anhand einiger Beispiele herausfinden.
Um die folgenden Beispiele auszuführen, erstellen Sie die folgenden Verzeichnisse und Dateien.
mkdir aa
mkdir bb
touch file1
touch aa/file1
touch bb/file3
So erstellen Sie diese Struktur:
$ tree
.
├── aa
│ └── file1
├── bb
│ └── file3
└── file1
Verwenden Sie nun find, um nach benannten Verzeichnissen zu suchen aa. Kein Problem hier.
$ find . -type d -name aa
./aa
Suchen Sie nach allen Verzeichnissen außer aa und wir erhalten das aktuelle Verzeichnis .und ./bb, was auch Sinn macht.
$ find . -type d ! -name aa
.
./bb
So weit so gut, aber wenn wir verwenden -prune, gibt find das Verzeichnis zurück, das wir bereinigen, was mich anfangs verwirrte, weil ich erwartet hatte, dass es alle anderen Verzeichnisse zurückgibt und nicht dasjenige, das beschnitten wird.
$ find . -type d -name aa -prune
./aa
Der Grund, warum das zu bereinigende Verzeichnis zurückgegeben wird, wird nicht im -pruneAbschnitt der Manpages erläutert, wie in Timos Antwort angegeben , sondern im EXPRESSIONSAbschnitt:
Wenn der Ausdruck keine anderen Aktionen als enthält -prune,
-printwird er für alle Dateien ausgeführt, für die der Ausdruck wahr ist.
Dies bedeutet, dass der Ausdruck, da er mit dem aaVerzeichnisnamen übereinstimmt , als wahr ausgewertet und gedruckt wird, da find implizit ein -printam Ende des gesamten Befehls hinzufügt . Es wird jedoch kein hinzugefügt -print, wenn Sie die Aktion absichtlich -o -printselbst zum Ende hinzufügen :
find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3
Hier fügt der Befehl find KEIN Implizites -printmehr hinzu, sodass das Verzeichnis, das wir beschneiden ( aa), nicht gedruckt wird.
Wenn wir also eine Klausel hinzufügen, die nach Dateien mit einem Dateinamenmuster file*nach dem sucht -o, müssen Sie -printam Ende dieser zweiten Klausel eine folgende setzen:
find . \( -type d -name aa -prune \) -o \( -type f -name 'file*' -print \)
./file1
./bb/file3
Der Grund, warum dies funktioniert, ist der gleiche: Wenn Sie -printin der zweiten Klausel keine -pruneeinfügen, fügt find -printam Ende des Befehls automatisch eine hinzu , da die Aktion keine andere als die Aktion enthält , wodurch die -pruneKlausel die druckt beschnittenes Verzeichnis:
find . \( \( -type d -name aa -prune \) -o \( -type f -name 'file*' \) \) -print
./aa
./file1
./bb/file3
Im Allgemeinen müssen Sie den -printBefehl in die zweite Klausel einfügen. Wenn Sie es wie das Originalplakat in der Mitte platzieren, funktioniert es nicht richtig, da die zu beschneidenden Dateien sofort gedruckt werden und die zweite Klausel keine Chance hat, die gewünschten Dateien auszuwählen:
find . \( -type d -name aa -prune -o -print \) -o \( -type f -name 'file*' \)
.
./file1
./bb
./bb/file3
Leider hat das Originalplakat den obigen Befehl falsch platziert, indem es -printan der falschen Stelle platziert wurde. Es könnte für seinen speziellen Fall funktioniert haben, aber es funktioniert im allgemeinen Fall nicht.
Es gibt Tausende von Menschen, die Schwierigkeiten haben zu verstehen, wie es -prunefunktioniert. Die findManpage sollte aktualisiert werden, um die unendliche weltweite Verwirrung über diesen Befehl zu vermeiden.
-print, sonst gilt das Implizite-printfür die gesamte Bedingung