comment effectuer une opération grep sur tous les fichiers d'un répertoire

219

Travailler avec xenserver, et je veux exécuter une commande sur chaque fichier qui se trouve dans un répertoire, en récupérant des éléments de la sortie de la commande et en les ajoutant dans un fichier.

Je suis clair sur la commande que je veux utiliser et sur la façon d'extraire les chaînes selon les besoins.

Mais ce que je ne sais pas, c'est comment faire exécuter cette commande sur chaque fichier, en passant au suivant, jusqu'à ce qu'aucun autre fichier ne soit trouvé.

user2147075
la source

Réponses:

228

grep $PATTERN *serait suffisant. Par défaut, grep ignorerait tous les sous-répertoires. Cependant, si vous souhaitez les parcourir, grep -r $PATTERN *c'est le cas.

umi
la source
37
"grep -r $ PATTERN." est suffisant. Pour la grep récursive, vous n'avez pas besoin de spécifier tous les fichiers
Cougar
1
Comment inclure plusieurs extensions? Par exemple. "* .cpp", "* .h"?
Tomáš Zato - Rétablir Monica
1
@ Tomáš Zato, fournir simplement tous vos modèles au lieu de fichiers de *: grep $PATTERN *.cpp *.h. Si vous avez besoin de règles plus spécifiques pour quels fichiers doivent être reçus, utilisez la findcommande (vérifiez la réponse de Rob).
umi
@umi Si j'exécute, les grep -r x .résultats proviennent de tous les fichiers de toutes les extensions. Si je cours, grep -r x *.scssje ne reçois aucun résultat.
Chris
1
@Chris il est possible que vous n'ayez pas de *.scssfichiers dans le répertoire courant mais quelque part plus profondément dans les sous-répertoires afin que grep ne recherche pas tous les fichiers que vous vouliez. Vous devez utiliser l' --includeoption pour dire à grep de rechercher récursivement des fichiers qui correspondent à des modèles spécifiques: grep -r x --include '*.scss' . (notez les guillemets, ils empêchent le modèle d'être développé par le shell). Ou utilisez simplement find(voir la réponse de Rob).
umi
169

Sous Linux, j'utilise normalement cette commande pour grep récursivement pour un texte particulier dans un dir

grep -rni "string" *

où,

r = récursif c'est-à-dire, rechercher des sous-répertoires dans le répertoire courant
n = pour imprimer les numéros de ligne sur stdout
i = recherche insensible à la casse

Narain
la source
32

Utilisez find. Sérieusement, c'est le meilleur moyen, car vous pouvez alors vraiment voir sur quels fichiers il fonctionne:

find . -name "*.sql" -exec grep -H "slow" {} \;

Remarque, le -H est spécifique au mac, il affiche le nom de fichier dans les résultats.

Rob
la source
7
Si vous décidez d'utiliser find, diriger la sortie xargsplutôt que d'utiliser -execceci sera beaucoup plus rapide, car -execengendre un nouveau processus pour chaque grep, et la surcharge devient importante avec un grand nombre de fichiers. Les avertissements standard concernant les espaces dans les noms de fichiers s'appliquent à xargs.
Barton Chittenden
2
À quoi cela ressemblerait-il exactement? J'oublie toujours la xargssyntaxe.
Brian Peterson
3
@BrianPeterson ce serait quelque chose comme ça:find . -iname "*.sql" -print0 | xargs -0 grep "slow"
MediaVince
4

Pour rechercher dans tous les sous-répertoires, mais uniquement dans des types de fichiers spécifiques , utilisez grep avec --include.

Par exemple, rechercher récursivement dans le répertoire courant, du texte dans * .yml et * .yaml:

grep "text to search" -r . --include=*.{yml,yaml}
Noam Manos
la source
1

Si vous souhaitez exécuter plusieurs commandes, vous pouvez utiliser:

for I in `ls *.sql`
do
    grep "foo" $I >> foo.log
    grep "bar" $I >> bar.log
done
Bryan
la source