web-dev-qa-db-fra.com

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

Je veux trouver tous les fichiers contenant une chaîne de texte spécifique. La commande grep fonctionne, mais je ne sais pas comment l'utiliser pour tous les répertoires (je ne peux le faire que pour mon répertoire actuel). J'ai essayé de lire man grep, mais cela n'a apporté aucune aide.

341
Smile.Hunter

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'option -l (ou --files-with-matches) est utilisée pour imprimer uniquement les noms de fichiers des fichiers correspondants, et non les lignes correspondantes (cela pourrait également améliorer la vitesse, étant donné que grep cesse de lire un fichier pour la première fois qui correspond à cette option).
441
enzotib

Si vous recherchez des lignes correspondant aux fichiers, ma commande préférée est:

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

path/to/files peut être . pour effectuer une recherche dans le répertoire en cours

Autres options que je trouve très utiles:

  • -I ignore les fichiers binaires (complément: -a traite tous les fichiers en tant que texte)
  • -F traite search term comme un littéral, pas comme une expression régulière
  • -i faire une recherche insensible à la casse
  • --color=always pour forcer les couleurs même lorsque vous passez par less. Pour rendre les couleurs de support less, vous devez utiliser l'option -r:

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

Example output

156
Lekensteyn

Je crois que vous pouvez utiliser quelque chose comme ceci:

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

Explication à partir de commentaires

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

  • -type f spécifie qu'il doit traiter uniquement les fichiers, pas 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 en tant qu'argument, en remplaçant {} par le nom de fichier
23
dmityugov

Ma commande par défaut est

grep -Rin string *

J'utilise un capitole 'R' parce que ls l'utilise de manière récursive. Puisque grep accepte les deux, aucune raison de ne pas l'utiliser.

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

18
user606723

Si vous voulez essayer quelque chose de nouveau, donnez ack un coup. La commande permettant de rechercher de manière récursive le répertoire en cours pour string est la suivante:

ack string

L'installation est assez simple:

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

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

11
Konrad Rudolph

La commande rgrep est dédiée à ce besoin

Si non disponible, vous pouvez l'obtenir comme ceci

mkdir -p ~/bin
cd ~/bin
wget http://sdjf.esmartdesign.com/files/rgrep
chmod +x rgrep

Vous pouvez directement définir vos options grep par défaut comme décrit ci-dessus.

J'utilise personnellement

[[  ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"
args="${args:--Hns} --color=auto"

sujet associé: comment toujours utiliser rgrep avec color

3
mnono

Mise à jour 2:

Cette ligne de commandes utilisant find et grep résout le problème:

$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +

--color=<always or auto> pour la sortie en couleur:

$ find path_to_search_in -type f \
            -exec grep --color=always -in searchString {} 2>/dev/null +

Exemple:

$ find /tmp/test/ -type f -exec grep --color=auto -in "Search string" {} 2>/dev/null +

Un exemple exécuté dans l'instantané ci-dessous: snap1


Mise à jour 1:

Vous pouvez essayer le code suivant. en tant que fonction dans votre .bashrc ou .bash_aliases ou dans un script:

wherein () 
{ 
    for i in $(find "$1" -type f 2> /dev/null);
    do
        if grep --color=auto -i "$2" "$i" 2> /dev/null; then
            echo -e "\033[0;32mFound in: $i \033[0m\n";
        fi;
    done
}

Utilisation: wherein /path/to/search/in/ searchkeyword

exemple:

$ wherein ~/Documents/ "hello world"

(Remarque: comme @enzotib le suggère dans les commentaires ci-dessous, cela ne fonctionne pas avec les fichiers/répertoires contenant des espaces dans leurs noms.)


Message original

Pour rechercher la chaîne et afficher uniquement cette ligne avec la chaîne de recherche:

$ for i in $(find /path/of/target/directory -type f); do \
    grep -i "the string to look for" "$i"; done

par exemple.:

$ for i in $(find /usr/share/applications -type f); \
    do grep -i "web browser" "$i"; done

Pour afficher le nom de fichier contenant la chaîne de recherche:

$ for i in $(find /path/of/target/directory -type f); do \
    if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

par exemple.:

$ for i in $(find /usr/share/applications -type f); \
    do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
    fi; done;
2
precise

grep ( GNU ou BSD )

Vous pouvez utiliser l'outil grep pour effectuer une recherche récursive dans le dossier actuel avec le paramètre -r, par exemple:

grep -r "pattern" .

Remarque: -r - Effectuez une recherche récursive dans les sous-répertoires.

Pour effectuer une recherche dans des fichiers spécifiques, vous pouvez utiliser un syntaxe globbing tel que:

grep "class foo" **/*.c

Remarque: En utilisant option de sélection (**), tous les fichiers sont analysés de manière récursive avec une extension ou un modèle spécifique. Pour activer cette syntaxe, exécutez: shopt -s globstar . Vous pouvez également utiliser **/*.* pour tous les fichiers (sauf les fichiers cachés et sans extension) ou tout autre motif.

Si vous estimez que votre argument est trop long, envisagez de préciser votre recherche ou utilisez la syntaxe find à la place, par exemple:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

Vous pouvez également utiliser ripgrep .

ripgrep

Si vous travaillez sur des projets plus volumineux ou de gros fichiers, vous devriez plutôt utiliser ripgrep, comme:

rg "pattern" .

Consultez la documentation, les étapes d'installation ou le code source sur la page du projet GitHub .

C'est beaucoup plus rapide que n'importe quel autre outil comme GNU / BSDgrep , ucg , ag , sift , ack , pt ou similaire, car il est construit sur le moteur de regex de Rust qui utilise des automates finis, SIMD et des optimisations littérales agressives pour rendre la recherche très rapide.

Il prend en charge les modèles ignorés spécifiés dans les fichiers .gitignore, de sorte qu'un même chemin de fichier peut être comparé à plusieurs modèles globaux simultanément.


Vous pouvez utiliser les paramètres communs tels que:

  • -i - Recherche insensible.
  • -I - Ignore les fichiers binaires.
  • -w - Recherche des mots entiers (par opposition à la correspondance partielle de mots).
  • -n - Affichez la ligne de votre match.
  • -C/--context (Exemple: -C5) - Augmente le contexte pour afficher le code environnant.
  • --color=auto - Marquez le texte correspondant.
  • -H - Affiche le nom du fichier où se trouve le texte.
  • -c - Affiche le nombre de lignes correspondantes. Peut être combiné avec -H.
1
kenorb

Je le fais en utilisant xargs, une commande très sous-estimée

find ./ -type f -print0 | xargs -0 grep 'string_you_are_looking_for'

find ./ vous donne une liste récursive de tous les fichiers d'un dossier en cours, puis vous dirigez celui-ci vers xargs qui exécute la commande grep sur chacun de ces fichiers

1
deadprogrammer

Je sais qu'il existe de nombreuses réponses ici, mais voici une alternative si vous souhaitez ajouter d'autres restrictions lors de la recherche dans les fichiers:

find . -type f -exec grep --quiet string_to_look_for {} ';' -print

Cela fonctionne car grep retournera 0 s'il a trouvé un résultat, 1 sinon. Par exemple, vous pouvez trouver des fichiers de 1 Mo de taille importante et contenant quelque chose:

find . -type f -exec grep --quiet string_to_look_for {} ';' -size 1M -print

Pour plusieurs besoins, vous voudrez probablement utiliser l'indicateur d'optimiseur -O qui existe dans GNU grep.

0
Ztyx

Un script (find-in-code) pour rechercher en C, code CPP:

#!/bin/sh

find . \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" \) -type f -print0 | xargs -0 grep --color -n "$1"

Utilisation:

find-in-code "search string"
0
nvd