Comment exécuter find -exec?


Réponses:


710

Vous avez manqué un ;(échappé ici \;pour empêcher le shell de l'interpréter) ou un +et a {}:

find . -exec grep chrome {} \;

ou

find . -exec grep chrome {} +

finds'exécutera grepet remplacera {}par le nom de fichier trouvé. La différence entre ;et +est qu’une ;seule grepcommande est exécutée pour chaque fichier alors qu’avec +autant de fichiers que possible, les paramètres sont indiqués en même greptemps.


30
Si vous utilisez le \; La construction de fin, grep, est transmise un fichier à la fois. Par conséquent, elle n’affiche pas le nom du fichier par défaut, mais uniquement les lignes correspondantes. Pour obtenir une liste de fichiers, ajoutez plutôt use grep -lsdans la construction find.
Caleb

9
find . -exec grep foo {} +vous montrera une sortie comme celle-ci./dir/file.py:from foo import bar
sg

10
find . -exec grep foo {} \;va vous montrer la sortie comme çafrom foo import bar
sg

9
find . -exec grep -l foo {} +va vous montrer la sortie comme ça./dir/file.py
sg

8
find . -exec grep -l foo {} \;va vous montrer la sortie comme ça./dir/file.py
sg

46

Vous n'avez pas besoin d'utiliser findpour cela du tout; grep est capable de gérer l’ouverture des fichiers à partir d’une liste globale de tout ce qui se trouve dans le répertoire courant:

grep chrome *

... ou même récursivement pour le dossier et tout ce qu'il contient:

grep chrome . -R

22
grep s'étouffera si l'extension passe par ARG_MAX. -R visitera tout en utilisant find on pourra plus facilement ajouter des primitives pour exclure certains fichiers (-name, etc.) ou même ne pas visiter les sous-arbres (-prune).
Mel

6
Bons points @Mel. Mon argument était que, selon toute vraisemblance, la partie demanderesse rendait les choses plus complexes qu’elles n’auraient dû être en indiquant findquand on greppourrait faire le travail, mais dans certains cas, il serait plus efficace d’utiliser find pour affiner la liste des dossiers avant de sortir. à grep.
Caleb

4
@Mel grepne s'étouffe pas dans un tel cas, le execfait.
Chris Down

Ne fonctionne que si tous les fichiers se trouvent dans le même répertoire, pas lorsqu'ils sont répartis sur des sous-répertoires.
Yaba

1
@Yaba Ma réponse indique comment gérer le cas de fichiers répartis sur des sous-répertoires.
Caleb

18
find . | xargs grep 'chrome'

vous pouvez aussi faire:

find . | xargs grep 'chrome' -ls

Le premier vous montre les lignes dans les fichiers, le second ne fait que lister les fichiers.

L'option de Caleb est plus nette, moins de frappes.


11
Le problème, xargsc'est qu'il s'attend à ce que son entrée soit citée d'une manière particulière qui findne produit pas. Donc, find … | xargs …ne fonctionne pas si vous avez des noms de fichiers contenant des espaces ou \'".
Gilles

3
@ Gilles Vous pouvez contourner ce problème en utilisant quelque chose comme find . | xargs -n1 -iX grep "X" 'chrome'pour que les arguments soient alimentés un par un et cités. De toute évidence, c’est un moyen terriblement inefficace de traiter cet exemple, mais dans certaines situations, c’est agréable.
Caleb

Pour être complet, nous devrions également mentionner l'option -i pour l'insensibilité à la casse avec 'grep'. De plus, il y a -iname en recherche pour insensibilité à la casse.
Mathew

9
@Caleb: Le seul moyen fiable de xargsgérer les noms de fichiers Linux est d' find ... -print0 | xargs -0utiliser NUL comme séparateur. Alternative - xargs -d '\n'utilisation de newline comme séparateur, fiabilité à 99%.
Grawity

J'utilise cela souvent, mais cela échouera pour de très longues listes de noms de fichiers, à ce moment-là, trouver -exec devient le gagnant.
Spacemoose

5

Trouver est un moyen et vous pouvez essayer the_silver_searcheralors tout ce que vous devez faire est

ag chrome

Il va chercher chrome dans tous les fichiers (inclure les sous-répertoires) et il est plus rapide que trouver


Il existe également un pt (chercheur de platine, disponible sur github.com/monochromegane/the_platinum_searcher ) qui, à mon humble avis , fait le travail plus rapidement - n’a peut-être pas d'importance s'il n'y a que quelques fichiers.
Hopping Bunny

1

Pour voir la liste des fichiers au lieu des lignes:

grep -l "chrome" *

ou:

grep -r -l "chrome" .

1

Voici un exemple de la façon dont j'utilise habituellement find / exec ...

find  . -name "*.py" -print -exec fgrep hello {} \;

Ceci recherche récursivement tous les fichiers .py et, pour chaque fichier, imprime le nom du fichier et fgrep pour 'hello' sur ce fichier (pour chaque). La sortie ressemble à (en ai juste lancé une aujourd'hui):

./r1.py
./cgi-bin/tst1.py
print "hello"
./app/__init__.py
./app/views.py
./app/flask1.py
./run.py
./tst2.py
print "hello again"

1
ne gâchez pas votre flux de travail, mais vous pourriez aimer: find . -name "*.py" -exec fgrep -l hello {} \; - il imprimera les noms de fichier des fichiers correspondants, et rien d'autre
Jeff Schaller
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.