448 votes

Comment utiliser la commande "grep" pour trouver du texte, y compris des sous-répertoires ?

Je veux trouver tous les fichiers qui contiennent une chaîne de texte spécifique. Le site grep fonctionne, mais je ne sais pas comment l'utiliser pour chaque répertoire (je ne peux le faire que pour mon répertoire courant). J'ai essayé de lire man grep mais cela n'a rien donné.

615voto

enzotib Points 86709

Il serait préférable d'utiliser

grep -rl "string" /path

  • -r (ou --recursive ) est utilisée pour parcourir également tous les sous-répertoires de /path alors que
  • -l (ou --files-with-matches ) est utilisée pour n'imprimer que les noms des fichiers correspondants, et non les lignes correspondantes (cela pourrait également améliorer la vitesse, étant donné que l'option grep arrêter la lecture d'un fichier au premier match avec cette option).

201voto

Lekensteyn Points 162346

Si vous cherchez à faire correspondre des lignes dans des fichiers, ma commande préférée est :

grep -Hrn 'search term' path/to/files
  • -H entraîne l'impression du nom de fichier (implicite lorsque plusieurs fichiers sont recherchés)
  • -r effectue une recherche récursive
  • -n entraîne l'impression du numéro de ligne

path/to/files peut être . pour rechercher dans le répertoire courant

D'autres options que je trouve très utiles :

  • -I ignorer les fichiers binaires (complément : -a traiter tous les fichiers comme du texte)

  • -F traiter search term comme un littéral, pas une expression régulière

  • -i effectuer une recherche insensible à la casse

  • --color=always pour forcer les couleurs même en passant par le pipeline less . Pour faire less prennent en charge les couleurs, vous devez utiliser l'option -r option :

    grep -Hrn search . | less -r
  • --exclude-dir=dir utile pour exclure des répertoires comme .svn y .git .

Example output

1 votes

@alper Try grep --exclude='*~' ...

26voto

Daniel Points 143

Je crois que vous pouvez utiliser quelque chose comme ça :

find /path -type f -exec grep -l "string" {} \;

Explication des commentaires

find est une commande qui vous permet de trouver des fichiers et d'autres objets comme des répertoires et des liens dans les sous-répertoires d'un chemin donné. Si vous ne spécifiez pas un masque que les noms de fichiers doivent respecter, elle énumère tous les objets de répertoire.

  • -type f spécifie qu'il doit traiter uniquement les fichiers, et non les répertoires, etc.
  • -exec grep spécifie que pour chaque fichier trouvé, il doit exécuter la commande grep, en lui passant son nom de fichier comme argument, en remplaçant {} avec le nom de fichier

3 votes

Juste pour ceux qui ne le savent pas, l'ajout de -name '*.py' restreint les correspondances aux fichiers se terminant par '.py'.

0 votes

J'aime bien que cela couvre les clients qui n'ont pas le paramètre -R dans leur commande grep.

0 votes

Si vous voulez que la ligne et le nom de fichier correspondants soient imprimés, faites une exécution comme : ... -exec bash -c 'grep -r "mystring" {} && echo {}' \;

23voto

user606723 Points 1782

Ma commande par défaut est

grep -Rin string *

J'utilise un "R" majuscule parce que ls l'utilise pour la récurrence. Puisque grep accepte les deux, il n'y a aucune raison de ne pas l'utiliser.

EDIT : par HVNSweeting, apparemment -R suivra les liens symboliques, alors que -r ne le fera pas.

1 votes

Pour rechercher également dans les fichiers cachés, exécutez shopt -s dotglob (souvenez-vous -s comme "set"). Soyez prudent lorsque vous supprimez des fichiers. Si vous avez activé dotglob, rm -r * supprime tout ce qui se trouve dans le répertoire courant, mais también le répertoire situé au-dessus parce que .. matches. Pour désactiver dotglob, utilisez shopt -u dotglob ("unset"). Les changements sont cependant temporaires, ils ne s'appliquent qu'à la Shell actuelle.

1 votes

J'avais oublié ça. Y a-t-il un moyen de le définir pour une seule ligne ? quelque chose comme shopt -s dotglob & <grep cmd> & shopt -y dotglob seulement plus pratique ? De cette façon, nous n'aurons pas à nous soucier de le réinitialiser.

0 votes

De plus, il est probablement plus facile d'utiliser grep -Rin string . dans la plupart de ces cas. J'utilise simplement * parce que cela semble venir plus naturellement.

13voto

The_cobra666 Points 167

Si vous êtes prêt à essayer quelque chose de nouveau, donnez à ack un coup de feu. La commande permettant de rechercher de manière récursive dans le répertoire courant les string est :

ack string

L'installation est assez simple :

curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3

(A condition que vous ayez déjà le répertoire ~/bin et c'est de préférence dans votre PATH .)

2 votes

Ou simplement apt-get install ack-grep (, et ajouter l'alias ack=ack-grep à votre .bashrc)

0 votes

Quels sont les derniers paramètres de la chmod faire ? Sont-elles spécifiques pour chmod ou sont-ils liés à bash (le !#:3 partie) ?

0 votes

@ElliottDarfink C'est l'utilisation de Bash's fonction historique - ! est un indicatif d'événement . Ils sont assez puissants pour éviter les répétitions. !#:3 référence le troisième jeton de la ligne de commande jusqu'à présent, c'est-à-dire ~/bin/ack dans ce cas.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X