J'étais confus quant à la raison pour laquelle les répertoires élagués étaient également imprimés par la find
commande et certains autres détails complexes sur la façon dont cela -prune
fonctionnait, mais j'ai pu le comprendre avec quelques exemples.
Pour exécuter les exemples ci-dessous, créez les répertoires et fichiers suivants.
mkdir aa
mkdir bb
touch file1
touch aa/file1
touch bb/file3
Pour créer cette structure:
$ tree
.
├── aa
│ └── file1
├── bb
│ └── file3
└── file1
Utilisez maintenant find pour rechercher les répertoires nommés aa
. Pas de problème ici.
$ find . -type d -name aa
./aa
Recherchez tous les répertoires autres que aa et nous obtenons le répertoire actuel .
et ./bb
, ce qui est également logique.
$ find . -type d ! -name aa
.
./bb
Jusqu'à présent, tout va bien, mais lorsque nous l'utilisons -prune
, find renvoie le répertoire que nous élaguons, ce qui m'a d'abord dérouté car je m'attendais à ce qu'il renvoie tous les autres répertoires et non celui en élagage.
$ find . -type d -name aa -prune
./aa
La raison pour laquelle il retourne le répertoire en cours d'élagage est expliquée, non pas dans la -prune
section des pages de manuel comme indiqué dans la réponse de Timo , mais dans la EXPRESSIONS
section:
Si l'expression ne contient aucune action autre que -prune
,
-print
est effectuée sur tous les fichiers pour lesquels l'expression est vraie.
ce qui signifie que, puisque l'expression correspond au aa
nom du répertoire, alors l'expression sera évaluée à true et elle sera imprimée car find ajoute implicitement un -print
à la fin de la commande entière. -print
Cependant, cela n'ajoutera pas un si vous ajoutez vous-même l'action -o -print
à la fin:
find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3
Ici, la commande find N'ajoute -print
plus d' implicite , donc le répertoire que nous élaguons ( aa
) ne sera pas imprimé.
Donc, enfin, si nous ajoutons une clause qui recherche des fichiers avec un modèle de file*
nom de fichier après le -o
, alors vous devez mettre un -print
à la fin de cette deuxième clause comme ceci:
find . \( -type d -name aa -prune \) -o \( -type f -name 'file*' -print \)
./file1
./bb/file3
La raison pour laquelle cela fonctionne est la même: si vous ne mettez pas de a -print
dans la deuxième clause, alors comme il n'y a aucune action autre que l' -prune
action, find ajoutera -print
automatiquement un à la FIN de la commande, provoquant l' -prune
impression de la clause répertoire élagué:
find . \( \( -type d -name aa -prune \) -o \( -type f -name 'file*' \) \) -print
./aa
./file1
./bb/file3
En général, vous devez placer la -print
commande dans la deuxième clause. Si vous le placez au milieu comme l'a fait l'affiche originale, cela ne fonctionnera pas correctement car les fichiers en cours d'élagage seront imprimés immédiatement et la deuxième clause n'aura pas la possibilité de choisir les fichiers souhaités:
find . \( -type d -name aa -prune -o -print \) -o \( -type f -name 'file*' \)
.
./file1
./bb
./bb/file3
Donc, malheureusement, l'affiche originale a mal reçu la commande ci-dessus en plaçant -print
le mauvais endroit. Cela pourrait avoir fonctionné pour son cas spécifique, mais cela ne fonctionne pas dans le cas général.
Il y a des milliers de personnes qui ont du mal à comprendre comment ça -prune
marche. La find
page de manuel doit être mise à jour afin d'éviter la confusion mondiale sans fin à propos de cette commande.
-print
, sinon l'implicite-print
s'applique à l'ensemble de la condition