Question

Je ne comprends pas tout à fait l'exemple de la man find, quelqu'un peut me donner quelques exemples et des explications? Puis-je combiner l'expression régulière en elle?


La question plus détaillée est comme ceci:

Ecrire un script shell, changeall, qui a une interface comme changeall [-r|-R] "string1" "string2". Il trouvera tous les fichiers avec un suffixe de .h, .C, .cc ou .cpp et changer toutes les occurrences de string1 à string2. -r est l'option pour rester en courant uniquement dir ou y compris de subdir.

NOTE:

  1. Pour le cas non récurrent, ls n'est pas autorisé, nous ne pouvions utiliser find et sed.
  2. J'ai essayé find -depth mais il n'a pas été retenue. Voilà pourquoi je me demandais si -prune pourrait aider, mais ne comprenais pas l'exemple de man find.

EDIT2: Je faisais mission, je ne l'ai pas poser des questions dans beaucoup de détails parce que je voudrais terminer moi-même. Depuis que je déjà fait et la main dans, maintenant, je peux dire toute la question. De plus, je suis parvenu à terminer la mission sans utiliser -prune, mais je voudrais apprendre de toute façon.

Était-ce utile?

La solution

La chose que j'avais trouvé confus au sujet au sujet -prune est que c'est une action (comme -print), pas un test (comme -name). Il modifie la liste "à faire", mais retourne toujours true .

Le schéma général pour l'utilisation -prune est la suivante:

find [path] [conditions to prune] -prune -o \
            [your usual conditions] [actions to perform]

Vous voulez à peu près toujours le -o (logique) immédiatement après -prune, parce que la première partie du test (jusqu'au -prune) retournera false pour les choses que vous voulez réellement (c.-à- : les trucs que vous ne pas veulent élaguer)

.

Voici un exemple:

find . -name .snapshot -prune -o -name '*.foo' -print

trouvera les fichiers « * .foo » qui ne sont pas sous répertoires « .snapshot ». Dans cet exemple, -name .snapshot fait la [conditions to prune] et -name '*.foo' -print est [your usual conditions] et [actions to perform].

Remarques importantes :

  1. Si tout ce que vous voulez faire est d'imprimer les résultats que vous pourriez être utilisé pour quitter l'action de -print. Vous en général ne pas veulent le faire lors de l'utilisation -prune.

    Le comportement par défaut de trouver est « et » ensemble expression avec l'action -print s'il n'y a pas d'autres actions que -prune (ironiquement) à la fin. Cela signifie que l'écriture ceci:

    find . -name .snapshot -prune -o -name '*.foo'              # DON'T DO THIS
    

    est équivalent à écrire ceci:

    find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
    

    ce qui signifie qu'il va imprimer le nom du répertoire que vous la taille, ce qui est généralement pas ce que vous voulez. Au contraire, il est préférable de spécifier explicitement l'action -print si c'est ce que vous voulez:

    find . -name .snapshot -prune -o -name '*.foo' -print       # DO THIS
    
  2. Si votre « condition habituelle » arrive de faire correspondre les fichiers qui correspondent également à votre condition pruneau, ces fichiers pas être inclus dans la sortie. La façon de résoudre ce problème est d'ajouter un prédicat -type d à votre état pruneau.

    Par exemple, supposons que nous voulions élaguer un répertoire qui a commencé avec .git (ce qui est certes un peu artificiel - normalement il vous suffit de retirer la chose nommée exactement .git), mais à part ça voulait voir tous les fichiers, y compris les fichiers comme .gitignore. Vous pouvez essayer ceci:

    find . -name '.git*' -prune -o -type f -print               # DON'T DO THIS
    

    Ceci pas inclure .gitignore dans la sortie. Voici la version fixe:

    find . -type d -name '.git*' -prune -o -type f -print       # DO THIS
    

Astuce supplémentaire:. Si vous utilisez la version GNU de find, la page texinfo pour find a une explication plus détaillée que son manpage (comme est le cas pour la plupart des utilitaires GNU)

Autres conseils

Garde-toi -prune ne l'empêche pas de descendre dans tout Répertoire comme certains l'ont dit. Il empêche de descendre dans les répertoires correspondant au test, il est appliqué. Peut-être que quelques exemples aideront (voir le bas pour un exemple regex). Désolé pour ce qui est si long.

$ find . -printf "%y %p\n"    # print the file type the first time FYI
d .
f ./test
d ./dir1
d ./dir1/test
f ./dir1/test/file
f ./dir1/test/test
d ./dir1/scripts
f ./dir1/scripts/myscript.pl
f ./dir1/scripts/myscript.sh
f ./dir1/scripts/myscript.py
d ./dir2
d ./dir2/test
f ./dir2/test/file
f ./dir2/test/myscript.pl
f ./dir2/test/myscript.sh

$ find . -name test
./test
./dir1/test
./dir1/test/test
./dir2/test

$ find . -prune
.

$ find . -name test -prune
./test
./dir1/test
./dir2/test

$ find . -name test -prune -o -print
.
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2

$ find . -regex ".*/my.*p.$"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test/myscript.pl

$ find . -name test -prune -regex ".*/my.*p.$"
(no results)

$ find . -name test -prune -o -regex ".*/my.*p.$"
./test
./dir1/test
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test

$ find . -regex ".*/my.*p.$" -a -not -regex ".*test.*"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py

$ find . -not -regex ".*test.*"                   .
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2

Normalement, la manière native nous faisons les choses dans Linux et la façon dont nous pensons est de gauche à droite.
Donc, vous allez écrire ce que vous cherchez d'abord:

find / -name "*.php"

Ensuite, vous avez probablement entrer et réaliser frappé que vous obtenez trop de fichiers à partir répertoires vous ne souhaitez pas. Nous allons exclude / médias pour éviter de rechercher vos disques montés.
Vous devriez maintenant juste ajouter la ligne suivante à la commande précédente:

-print -o -path '/media' -prune

de sorte que la commande finale est la suivante:

find / -name "*.php" -print -o -path '/media' -prune

............... | <--- Inclure ---> | .................... | <---------- Exclure ---------> |

Je pense que cette structure est beaucoup plus facile et est en corrélation avec la bonne approche

Ajout aux conseils donnés dans d'autres réponses (je n'ai pas représentant de créer des réponses) ...

Lors de la combinaison -prune avec d'autres expressions, il y a une différence subtile de comportement selon lequel d'autres expressions sont utilisées.

@Laurence Gonsalves l'exemple trouvera les "*" .foo fichiers qui ne sont pas sous répertoires ".snapshot": -

find . -name .snapshot -prune -o -name '*.foo' -print

Cependant, cette courte main légèrement différente sera, peut-être par inadvertance, liste également le répertoire .snapshot (et tous les répertoires imbriqués .snapshot): -

find . -name .snapshot -prune -o -name '*.foo'

La raison en est (selon la page de manuel sur mon système): -

  

Si l'expression donnée ne contient aucune des primaires exec,   -ls, -OK, ou -print, l'expression donnée est effectivement remplacée par:

     

(given_expression) -print

Cela signifie que le deuxième exemple est l'équivalent d'entrer dans ce qui suit, en modifiant ainsi le regroupement des termes: -

find . \( -name .snapshot -prune -o -name '*.foo' \) -print

Cela a au moins été vu sur Solaris 5.10. Après avoir utilisé diverses saveurs de * nix pour environ 10 ans, je ne l'ai récemment cherché une raison pour laquelle cela se produit.

est un pruneau ne pas RECURSE à tout commutateur de répertoire.

A partir de la page man

  

Si -depth est pas donné, vrai;         si le fichier est un répertoire, ne descend pas en elle.     Si -depth est donnée, faux; aucun effet.

Fondamentalement, il ne sera pas desend dans les sous-répertoires.

Prenez cet exemple:

Vous avez les répertoires suivants

  • / home / test2
  • / home / test2 / test2

Si vous exécutez find -name test2:

Il renvoie les deux répertoires

Si vous exécutez find -name test2 -prune:

Il renvoie uniquement / home / test2 car il ne descendra pas dans / home / test2 pour trouver / home / test2 / test2

Je ne suis pas expert dans ce (et cette page a été très utile avec http://mywiki.wooledge.org / UsingFind )

Il suffit de remarquer -path est un chemin que correspond entièrement la chaîne / chemin qui vient juste après find (. dans les exemples de thèses) alors que -name correspond à tous les noms de base.

find . -path ./.git  -prune -o -name file  -print

bloque le répertoire .git dans votre répertoire courant ( comme conclusion à . )

find . -name .git  -prune -o -name file  -print

bloque tous les sous-répertoires .git récursive.

Notez que le ./ est extrêmement important !! -path doit correspondre à un chemin ancré à . ou tout ce qui vient juste trouver après si vous obtenez matchs sans elle (de l'autre côté du ou « -o ») il n'y probablement pas élagué! J'étais pas au courant de cette naïveté et il m'a mis d'utiliser -path quand il est grand quand vous ne voulez pas élaguer tout sous-répertoire avec le même nom de base: D

Afficher tout, y compris dir lui-même, mais pas son contenu à long ennuyeux:

find . -print -name dir -prune

Si vous lisez toutes les bonnes réponses ici ma compréhension est maintenant que ce qui suit tous les mêmes résultats:

find . -path ./dir1\*  -prune -o -print

find . -path ./dir1  -prune -o -print

find . -path ./dir1\*  -o -print
#look no prune at all!

Mais le dernier prendra beaucoup plus de temps comme il cherche encore à tout dir1. Je suppose que la vraie question est de savoir comment -or des résultats indésirables sans vraiment les chercher.

Je suppose que des moyens de pruneau faire les matchs passés non décents, mais marquer comme fait ...

http://www.gnu.org/software/findutils/ manuel / html_mono / find.html « Ceci est cependant pas due à l'effet de l'action « -prune »(ce qui empêche que la descente plus loin, il ne fait pas que nous ignorons ce point). Au lieu de cela, cet effet est dû à l'utilisation de -o. depuis le côté gauche de la « ou » état a réussi à ./src/emacs, il est nécessaire d'évaluer la main droite ( « -print ») du tout pour ce fichier particulier. "

find construit une liste de fichiers. Il applique le prédicat que vous avez fourni à chacun et renvoie ceux qui passent.

Cette idée que -prune moyens excluent des résultats était vraiment déroutant pour moi. Vous pouvez exclure un fichier sans pruneau:

find -name 'bad_guy' -o -name 'good_guy' -print  // good_guy

Tout -prune fait est de modifier le comportement de la recherche. Si le match actuel est un répertoire, il est dit « hey find, ce fichier que vous venez jumelé, ne pas y descendre » . Il supprime juste cet arbre (mais pas le fichier lui-même) dans la liste des fichiers à la recherche.

Il doit être nommé -dont-descend.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top