web-dev-qa-db-fra.com

Comment puis-je exclure des répertoires de grep -R?

Je veux parcourir tous les sous-répertoires, à l'exception du répertoire "node_modules".

565
TIMEX

SOLUTION 1 (combinez find et grep)

Le but de cette solution n'est pas de traiter les performances de grep mais de montrer une solution portable: devrait également fonctionner avec busybox ou GNU version antérieure à 2.5.

Utilisez find pour exclure les répertoires foo et bar:

find /dir \( -name foo -Prune \) -o \( -name bar -Prune \) -o -name "*.sh" -print

Puis combinez find et l’utilisation non récursive de grep, en tant que solution portable:

find /dir \( -name node_modules -Prune \) -o -name "*.sh" -exec grep --color -Hn "your text to find" {} 2>/dev/null \;

SOLUTION 2 (utilisation récursive de grep):

Vous connaissez déjà cette solution, mais je l’ajoute car c’est la solution la plus récente et la plus efficace. Notez qu'il s'agit d'une solution moins portable mais plus lisible par l'homme.

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search

Pour exclure plusieurs répertoires, utilisez --exclude-dir comme:

--exclude-dir={node_modules,dir1,dir2,dir3}

SOLUTION 3 (Ag)

Si vous recherchez fréquemment dans le code, Ag (The Silver Searcher) est une alternative beaucoup plus rapide que grep, qui est personnalisé pour la recherche de code. Par exemple, il ignore automatiquement les fichiers et les répertoires listés dans .gitignore, vous n'avez donc pas besoin de passer sans cesse les mêmes options d'exclusion encombrantes à grep ou find.

277
hornetbzz

Les versions récentes de GNU Grep (> = 2.5.2 ) fournissent:

--exclude-dir=dir

qui exclut les répertoires correspondant au modèle dir des recherches de répertoires récursives.

Alors tu peux faire:

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search

Pour un peu plus d'informations sur la syntaxe et l'utilisation, voir

Pour les anciens GNU Greps et POSIX Grep , utilisez find comme suggéré dans d'autres réponses.

Ou utilisez simplement ack ( Edit : ou The Silver Searcher ) et en finir avec ça!

918
Johnsyweb

Si vous souhaitez exclure plusieurs répertoires:

"r" pour récursif, "l" pour imprimer uniquement les noms de fichiers contenant des correspondances et "i" pour ignorer les distinctions entre les majuscules et les minuscules:

 
 grep -rli --exclude-dir = {dir1, dir2, dir3} mot-clé /path/to/search[.____. démocratie-.____.]

Exemple: je souhaite trouver des fichiers contenant le mot 'hello'. Je veux chercher dans tous mes répertoires Linux saufproc répertoire, boot répertoire, sys répertoire et root répertoire:

 
 grep -rli --exclude-dir = {proc, amorcer, root, sys} bonjour /

Remarque: l'exemple ci-dessus doit être root

Note 2 (selon @skplunkerin): ne pas ajouter d'espaces après les virgules dans {dir1,dir2,dir3}

69
Azodium

Cette syntaxe

--exclude-dir={dir1,dir2}

est développé par le shell (par exemple, Bash), pas par grep, dans ceci:

--exclude-dir=dir1 --exclude-dir=dir2

La citation empêchera le shell de l’étendre, cela ne fonctionnera donc pas:

--exclude-dir='{dir1,dir2}'    <-- this won't work

Les modèles utilisés avec --exclude-dir sont du même type que ceux décrits dans la page de manuel relative à l'option --exclude:

--exclude=GLOB
    Skip files whose base name matches GLOB (using wildcard matching).
    A file-name glob can use *, ?, and [...]  as wildcards, and \ to
    quote a wildcard or backslash character literally.

Le shell va généralement essayer développer un tel motif lui-même, pour éviter cela, vous devriez le citer:

--exclude-dir='dir?'

Vous pouvez utiliser les accolades et les motifs d’exclusion cités comme suit:

--exclude-dir={'dir?','dir??'}

Un modèle peut s'étendre sur plusieurs segments de chemin:

--exclude-dir='some*/?lse'

Cela exclurait un répertoire comme topdir/something/else.

39
Derek Veit

tilisez fréquemment ceci:

grep peut être utilisé avec -r (récursif), i (ignorer la casse) et -o (imprime uniquement les parties de lignes correspondantes). Pour exclure files, utilisez --exclude et pour exclure les répertoires, utilisez --exclude-dir.

En réunissant, vous obtenez quelque chose comme:

grep -rio --exclude={filenames comma separated} \
--exclude-dir={directory names comma separated} <search term> <location>

La décrire rend le son beaucoup plus compliqué qu’il ne l’est réellement. Plus facile à illustrer avec un exemple simple.

Exemple:

Supposons que je recherche le projet en cours pour tous les endroits où je définis explicitement la valeur de chaîne debugger au cours d'une session de débogage et que je souhaite maintenant vérifier/supprimer.

J'écris un script appelé findDebugger.sh et utilise grep pour rechercher toutes les occurrences. Pourtant:

Pour les exclusions de fichiers - je souhaite m'assurer que .eslintrc est ignoré (il existe en fait une règle relative à la fibre sur debugger et doit donc être exclu). De même, je ne veux pas que mon propre script soit référencé dans les résultats.

Pour les exclusions de répertoires - Je souhaite exclure node_modules car il contient de nombreuses bibliothèques qui font référence à debugger et je ne suis pas intéressé par ces résultats. De plus, je souhaite simplement omettre les répertoires cachés .idea et .git, car je ne me soucie pas de ces emplacements de recherche et je souhaite que la recherche reste performante.

Voici donc le résultat - je crée un script appelé findDebugger.sh avec:

#!/usr/bin/env bash
grep -rio --exclude={.eslintrc,findDebugger.sh} \
--exclude-dir={node_modules,.idea,.git} debugger .
13
arcseldon

Vous pouvez essayer quelque chose comme grep -R search . | grep -v '^node_modules/.*'

9
DipSwitch

Si vous recherchez du code dans un référentiel git et que node_modules se trouve dans votre .gitignore, vous pouvez utiliser git grep. git grep recherche les fichiers suivis dans l’arbre de travail en ignorant tout ce qui se trouve dans .gitignore

git grep "STUFF"
8
0xcaff

Très utile, surtout pour ceux qui traitent avec Node.js où nous voulons éviter de chercher dans "node_modules":

find ./ -not -path "*/node_modules/*" -name "*.js" | xargs grep keyword
4
Nestor Urquiza

Une simple commande de travail:

root/dspace# grep -r --exclude-dir={log,assetstore} "creativecommons.org"

Au-dessus, je grep pour le texte "creativecommons.org" dans le répertoire actuel "dspace" et exclure les dirs {log, assetstore}.

Terminé.

2
Dung
find . ! -name "node_modules" -type d 
1
Jack

celui-ci fonctionne pour moi

grep <stuff> -R --exclude-dir=<your_dir>

1
angelo.mastro

Beaucoup de réponses correctes ont été données ici, mais j'ajoute celui-ci pour souligner un point qui a déjà causé l'échec de certaines tentatives précipitées: exclude-dir prend un motif, pas un chemin d'accès à un répertoire .

Dites que votre recherche est:

grep -r myobject

Et vous remarquez que votre sortie est encombrée de résultats provenant du src/other/objects-folder. Cette commande not vous donnera le résultat souhaité:

grep -r myobject --exclude-dir=src/other/objects-folder

Et vous vous demandez peut-être pourquoi exclude-dir ne fonctionne pas! Pour exclure les résultats du objects-folder, procédez comme suit:

grep -r myobject --exclude-dir=objects-folder

En d'autres termes, utilisez simplement le nom du dossier, pas le chemin. Évident une fois que vous le savez.

De la page de manuel:

--exclude-dir = GLOB
Ignore tout répertoire de ligne de commande avec un suffixe de nom correspondant au modèle GLOB. Lors d'une recherche récursive, ignorez les sous-répertoires dont le nom de base correspond à GLOB. Ignorez les barres obliques de fin redondantes dans GLOB.

0
Nagev

Un moyen plus simple serait de filtrer vos résultats en utilisant "grep -v".

grep -i needle -R * | grep -v node_modules

0
Morris