J'étais confus quant à la raison pour laquelle les répertoires élagués étaient également imprimés par la findcommande et certains autres détails complexes sur la façon dont cela -prunefonctionnait, 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 -prunesection des pages de manuel comme indiqué dans la réponse de Timo , mais dans la EXPRESSIONSsection:
Si l'expression ne contient aucune action autre que -prune,
-printest effectuée sur tous les fichiers pour lesquels l'expression est vraie.
ce qui signifie que, puisque l'expression correspond au aanom 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. -printCependant, 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 -printplus 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 -printdans la deuxième clause, alors comme il n'y a aucune action autre que l' -pruneaction, find ajoutera -printautomatiquement un à la FIN de la commande, provoquant l' -pruneimpression 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 -printcommande 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 -printle 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 -prunemarche. La findpage de manuel doit être mise à jour afin d'éviter la confusion mondiale sans fin à propos de cette commande.
-print, sinon l'implicite-prints'applique à l'ensemble de la condition