Ich war verwirrt darüber, warum der find
Befehl 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 -prune
Abschnitt der Manpages erläutert, wie in Timos Antwort angegeben , sondern im EXPRESSIONS
Abschnitt:
Wenn der Ausdruck keine anderen Aktionen als enthält -prune
,
-print
wird er für alle Dateien ausgeführt, für die der Ausdruck wahr ist.
Dies bedeutet, dass der Ausdruck, da er mit dem aa
Verzeichnisnamen übereinstimmt , als wahr ausgewertet und gedruckt wird, da find implizit ein -print
am Ende des gesamten Befehls hinzufügt . Es wird jedoch kein hinzugefügt -print
, wenn Sie die Aktion absichtlich -o -print
selbst zum Ende hinzufügen :
find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3
Hier fügt der Befehl find KEIN Implizites -print
mehr 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 -print
am 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 -print
in der zweiten Klausel keine -prune
einfügen, fügt find -print
am Ende des Befehls automatisch eine hinzu , da die Aktion keine andere als die Aktion enthält , wodurch die -prune
Klausel 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 -print
Befehl 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 -print
an 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 -prune
funktioniert. Die find
Manpage sollte aktualisiert werden, um die unendliche weltweite Verwirrung über diesen Befehl zu vermeiden.
-print
, sonst gilt das Implizite-print
für die gesamte Bedingung