Ce que j'avais trouvé confus, -prune
c'est que c'est une action (comme -print
), pas un test (comme -name
). Il modifie la liste "à faire", mais renvoie toujours vrai .
Le schéma général d'utilisation -prune
est le suivant :
find [path] [conditions to prune] -prune -o \
[your usual conditions] [actions to perform]
Vous voulez à peu près toujours le -o
(OU logique) immédiatement après -prune
, car cette première partie du test (jusqu'à et y compris -prune
) retournera faux pour les choses que vous voulez réellement (c'est-à-dire: les choses que vous ne voulez pas tailler).
Voici un exemple:
find . -name .snapshot -prune -o -name '*.foo' -print
Cela trouvera les fichiers "* .foo" qui ne se trouvent pas dans les répertoires ".snapshot". Dans cet exemple, -name .snapshot
constitue le [conditions to prune]
, et -name '*.foo' -print
est [your usual conditions]
et [actions to perform]
.
Remarques importantes :
Si tout ce que vous voulez faire, c'est imprimer les résultats que vous pourriez avoir l'habitude de laisser de côté -print
. Vous ne voulez généralement pas le faire lors de l'utilisation -prune
.
Le comportement par défaut de find est de "et" l' expression entière avec l' -print
action s'il n'y a aucune action autre que -prune
(ironiquement) à la fin. Cela signifie que l'écriture de ceci:
find . -name .snapshot -prune -o -name '*.foo' # DON'T DO THIS
équivaut à écrire ceci:
find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
ce qui signifie qu'il affichera également le nom du répertoire que vous élaguez, ce qui n'est généralement pas ce que vous voulez. Au lieu de cela, il est préférable de spécifier explicitement l' -print
action si c'est ce que vous voulez:
find . -name .snapshot -prune -o -name '*.foo' -print # DO THIS
Si votre "condition habituelle" correspond à des fichiers qui correspondent également à votre condition d'élagage, ces fichiers ne seront pas inclus dans la sortie. La façon de résoudre ce problème consiste à ajouter un -type d
prédicat à votre condition de pruneau.
Par exemple, supposons que nous voulions éliminer tous les répertoires commençant par .git
(cela est certes quelque peu artificiel - normalement, il vous suffit de supprimer la chose nommée exactement .git
), mais à part cela, nous voulions voir tous les fichiers, y compris les fichiers comme .gitignore
. Vous pourriez essayer ceci:
find . -name '.git*' -prune -o -type f -print # DON'T DO THIS
Cela ne serait pas inclus .gitignore
dans la sortie. Voici la version fixe:
find . -name '.git*' -type d -prune -o -type f -print # DO THIS
Conseil supplémentaire: si vous utilisez la version GNU de find
, la page texinfo pour find
a une explication plus détaillée que sa page de manuel (comme c'est le cas pour la plupart des utilitaires GNU).
Laurence Gonsalves
la source
-prune
ne fonctionne pas seulement sur les répertoires (mais, pour les répertoires, il empêche également d'entrer les répertoires correspondant à cette condition, c'est-à-dire ici les répertoires correspondant à cela-name .snapshot
).-prune
lui-même qui en est la cause. Le problème est que l'opérateur ou "court-circuite", et ou a une priorité inférieure à et. Le résultat final est que si un fichier appelé.snapshot
est rencontré, il correspondra au premier-name
,-prune
ne fera rien (mais retournera vrai), puis le ou retournera vrai puisque son argument de gauche était vrai. L'action (par exemple:)-print
fait partie de son deuxième argument, elle n'a donc aucune chance de s'exécuter.-print
à la fin, je peux maintenant arrêter d'ajouter\! -path <pattern>
en plus de-prune
Normalement, la façon dont nous faisons les choses sous Linux et la façon dont nous pensons est de gauche à droite.
Donc, vous iriez d'abord écrire ce que vous cherchez:
Ensuite, vous appuyez probablement sur Entrée et réalisez que vous obtenez trop de fichiers à partir de répertoires que vous ne souhaitez pas. Excluons / media pour éviter de rechercher vos lecteurs montés.
Vous devez maintenant simplement ajouter ce qui suit à la commande précédente:
donc la commande finale est:
............... | <--- Inclure ---> | .................... | <- -------- Exclure ---------> |
Je pense que cette structure est beaucoup plus facile et correspond à la bonne approche
la source
find
est assez intelligent pour traiter la-prune
clause en premier. Hmmm, intéressant.-prune
partir de maintenant./media
, notant qu'il n'est pas appelé*.php
puis vérifiant s'il est actuellement à l'intérieur/media
, voyant qu'il l'est et donc sautant tout ce sous-arbre. C'est toujours de gauche à droite, cela ne fait aucune différence tant que les deux vérifications ne se chevauchent pas.Attention, -prune n'empêche pas de descendre dans n'importe quel répertoire comme certains l'ont dit. Il empêche de descendre dans des répertoires correspondant au test auquel il est appliqué. Peut-être que quelques exemples aideront (voir le bas pour un exemple d'expression régulière). Désolé pour le fait que ce soit si long.
la source
find . -name test -prune -o -print
: iow,-prune
est une action qui travaille sur fichiersAjout aux conseils donnés dans d'autres réponses (je n'ai pas de représentant pour créer des réponses) ...
Lors de la combinaison
-prune
avec d'autres expressions, il existe une différence subtile de comportement selon les autres expressions utilisées.L'exemple de @Laurence Gonsalves trouvera les fichiers "* .foo" qui ne se trouvent pas dans les répertoires ".snapshot": -
Cependant, ce raccourci légèrement différent
.snapshot
listera , peut-être par inadvertance, le répertoire (et tous les répertoires .snapshot imbriqués): -La raison en est (selon la page de manuel de mon système): -
Autrement dit, le deuxième exemple équivaut à saisir ce qui suit, modifiant ainsi le regroupement des termes: -
Cela a au moins été constaté sur Solaris 5.10. Ayant utilisé diverses saveurs de * nix pendant environ 10 ans, je n'ai récemment cherché une raison pour laquelle cela se produit.
la source
-prune
avec et sans-print
!L'élagage est un pas récursif à tout changement de répertoire.
Depuis la page de manuel
Fondamentalement, il ne descendra dans aucun sous-répertoire.
Prenez cet exemple:
Vous avez les répertoires suivants
Si vous exécutez
find -name test2
:Il renverra les deux répertoires
Si vous exécutez
find -name test2 -prune
:Il retournera uniquement / home / test2 car il ne descendra pas dans / home / test2 pour trouver / home / test2 / test2
la source
Je ne suis pas un expert en la matière (et cette page a été très utile avec http://mywiki.wooledge.org/UsingFind )
Nous venons de remarquer
-path
un chemin qui correspond entièrement à la chaîne / chemin qui vient juste aprèsfind
(.
dans ces exemples) où as-name
correspond à tous les noms de base.bloque le répertoire .git dans votre répertoire actuel ( comme votre recherche dans
.
)bloque récursivement tous les sous-répertoires .git.
Notez que
./
c'est extrêmement important !!-path
doit correspondre à un chemin ancré à.
ou tout ce qui vient juste après trouver si vous obtenez des correspondances sans (de l'autre côté du ou '-o
') là probablement pas élagué! J'étais naïvement inconscient de cela et cela m'a mis à utiliser -path quand c'est génial quand vous ne voulez pas tailler tous les sous-répertoires avec le même nom de base: Dla source
find bla/
vous aurez besoin de -pathbla/
.git (ou si vous placez un a*
à la place, cela ressemblerait plus à -name)Afficher tout, y compris dir lui-même mais pas son long contenu ennuyeux:
la source
Si vous lisez toutes les bonnes réponses ici, je comprends maintenant que les éléments suivants renvoient tous les mêmes résultats:
Mais le dernier prendra beaucoup plus de temps car il recherche toujours tout dans dir1. Je suppose que la vraie question est de savoir comment
-or
éliminer les résultats indésirables sans réellement les rechercher.Donc, je suppose que prune signifie que les matchs passés ne sont pas décents mais marquez-les comme terminés ...
http://www.gnu.org/software/findutils/manual/html_mono/find.html "Ceci n'est cependant pas dû à l'effet de l'action '-prune' (qui empêche seulement une nouvelle descente, il ne s'assure pas nous ignorons cet élément.) Au lieu de cela, cet effet est dû à l'utilisation de "-o". Puisque le côté gauche de la condition "ou" a réussi pour ./src/emacs, il n'est pas nécessaire d'évaluer le droit- côté ("-print") pour ce fichier particulier. "
la source
find
construit une liste de fichiers. Il applique le prédicat que vous avez fourni à chacun et renvoie ceux qui réussissent.Cette idée qui
-prune
signifie exclure des résultats était vraiment déroutante pour moi. Vous pouvez exclure un fichier sans élagage:Il
-prune
suffit de modifier le comportement de la recherche. Si la correspondance actuelle est un répertoire, il dit "héfind
, le fichier que vous venez de faire correspondre, ne descendez pas dedans" . Il supprime simplement cet arbre (mais pas le fichier lui-même) de la liste des fichiers à rechercher.Il doit être nommé
-dont-descend
.la source
Il y a pas mal de réponses; certains d'entre eux sont un peu trop lourds en théorie. Je laisserai pourquoi j'avais besoin de pruneau une fois, alors peut-être le besoin en premier / l'exemple type d'explication de est utile à quelqu'un :)
Problème
J'avais un dossier avec environ 20 répertoires de nœuds, chacun ayant son
node_modules
répertoire comme prévu.Une fois que vous entrez dans un projet, vous le voyez
../node_modules/module
. Mais tu sais comment c'est. Presque chaque module a des dépendances, donc ce que vous regardez ressemble plus àprojectN/node_modules/moduleX/node_modules/moduleZ...
Je ne voulais pas me noyer avec une liste avec la dépendance de la dépendance de ...
Connaître
-d n
/-depth n
, cela ne m'aurait pas aidé, car le répertoire principal / premier nœud_modules que je voulais pour chaque projet était à une profondeur différente, comme ceci:Comment puis-je obtenir le premier une liste de chemins se terminant au premier
node_modules
et passer au projet suivant pour obtenir le même?Entrer
-prune
Lorsque vous ajoutez
-prune
, vous aurez toujours une recherche récursive standard. Chaque "chemin" est analysé, et chaque trouvaille est crachée etfind
continue à creuser comme un bon gars. Mais c'est creuser pour plus denode_modules
ce que je ne voulais pas.Ainsi, la différence est que , dans l' un de ces chemins différents,
-prune
vontfind
arrêter de creuser plus loin dans cette voie particulière quand il a trouvé votre article. Dans mon cas, lenode_modules
dossier.la source