Je veux parcourir tous les sous-répertoires, à l'exception du répertoire "node_modules".
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
.
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!
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}
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
.
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 .
Vous pouvez essayer quelque chose comme grep -R search . | grep -v '^node_modules/.*'
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"
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
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é.
find . ! -name "node_modules" -type d
celui-ci fonctionne pour moi
grep <stuff> -R --exclude-dir=<your_dir>
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.
Un moyen plus simple serait de filtrer vos résultats en utilisant "grep -v".
grep -i needle -R * | grep -v node_modules