Question Comment utiliser la commande «grep» pour trouver du texte, y compris des sous-répertoires


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


292
2017-08-01 11:38


origine


grep -RIn <yor pattern> * Recherche des répertoires actuels dans tous les fichiers texte. Je ne sais pas comment faire ma recherche récursivement dans des modèles de fichiers comme * .C avec seulement grep
Wildcard avec --include="*.C" option, @ user311346, grâce à @Lekensteyn. - Bob Stein
Utilisez la combinaison find et grep pour rechercher de manière récursive une chaîne dans les sous-répertoires actuels et les sous-répertoires. Vérifie ça wilddiary.com/find-files-containing-my-text - Drona


Réponses:


Il serait préférable d'utiliser

grep -rl "string" /path

  • -r (ou --recursive) option permet de parcourir également tous les sous-répertoires de /path, tandis que
  • -l (ou --files-with-matches) est utilisée pour imprimer uniquement les noms de fichiers correspondants, et non les lignes correspondantes (cela pourrait également améliorer la vitesse, étant donné que grep arrêtez de lire un fichier au premier contact avec cette option).

375
2017-08-01 11:55



En fait, si "string" est un modèle de texte à trouver, il est préférable d'utiliser cette fonctionnalité, sinon quelqu'un peut rencontrer des problèmes lorsque la chaîne contient un caractère point ou spécial qui a un sens dans les expressions régulières et pas seulement un point , comme si. Alors j'utiliserais -rlF commutateurs, -F pour "chaîne fixe" (et pas regexp - par exemple). Bien sûr, si la tâche consistait à utiliser des expressions rationnelles, excusez-moi. Bien sûr, la même théorie sans -r aussi, je vois souvent que les gens supposent que grep effectue une recherche "text" et que cela peut causer des problèmes à des expressions spéciales qui signifient quelque chose comme une expression rationnelle. - LGB
Il y a aussi le -i drapeau qui ignore le cas. - Marco Ceppi♦
Je voudrais seulement montrer le --recursive option, il y a des tonnes d'options et de scénarios d'utilisation dont on peut parler. Je suis parti de la réponse acceptée par @dmityugov et modifié pour fonctionner sans find. - enzotib
@ N.N .: fait :-) - enzotib
@ScottBiggs: avec l'option --include '*.h' - enzotib


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

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 . rechercher dans le répertoire courant

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

  • -I ignore les fichiers binaires (complément: -a traiter tous les fichiers comme du texte)
  • -F traiter search term en tant que littéral, pas une expression régulière
  • -i faire une recherche insensible à la casse
  • --color=always pour forcer les couleurs même lors du passage less. Faire less couleurs de soutien, vous devez utiliser le -r option:

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

Example output


136
2017-08-01 12:27



-H sur un dossier est redondant, s'il y a plus d'un fichier, comme cela est probable. En fait, la page de manuel indique -H, --with-filename: Print the file name for each match. This is the default when there is more than one file to search. - enzotib
Je ne le savais pas, ça marchait toujours comme prévu. C'est ma commande par défaut lorsque vous recherchez des fichiers. - Lekensteyn
Existe-t-il un moyen de considérer uniquement les fichiers avec une extension, disons .a (et de les combiner avec -r)? - user2413
@ user2413 Essayez --include '*.*' - Lekensteyn
@enzotib Just a FYI: Je ne reçois pas la bonne sortie propre de chaque ligne dans chaque fichier où mon texte apparaît avec -rln ni -rl, mais je fais avec -Hrn. Redondant ou pas, il ressemble à la capture d'écran ci-dessus avec les options -Hrn. En outre, il ne semble pas que -n fonctionne sans -H. - SgtPooki


Je crois que vous pouvez utiliser quelque chose comme ceci:

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 tels que des répertoires et des liens dans des sous-répertoires d'un chemin donné. Si vous ne spécifiez pas un masque que les noms de fichiers doivent rencontrer, il énumère tous les objets de répertoire.

  • -type f spécifie qu'il ne doit traiter que des fichiers, pas des 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 argument, en remplaçant {} avec le nom de fichier

21
2017-08-01 11:48



Juste pour ceux qui ne connaissent pas, en ajoutant -name '*.py' restreint les correspondances aux fichiers se terminant par '.py'. - Daniel F
J'aime que cela couvre les clients qui n'ont pas -R implémenté dans leur commande grep. - Aviose


Ma commande par défaut est

grep -Rin string *

J'utilise un capitole «R» parce que ls l'utilise pour récursif. Puisque grep accepte les deux, aucune raison de ne pas l'utiliser.

EDIT: par HVNSweeting, apparemment -R suivra les liens symboliques où -r ne sera pas.


17
2017-08-01 14:43



Pour effectuer une recherche dans les fichiers cachés également, exécutez shopt -s dotglob (rappelles toi -s comme "set"). Soyez prudent lorsque vous supprimez des fichiers. Si vous avez activé dotglob, rm -r * supprime tout dans le répertoire en cours, mais aussi le répertoire ci-dessus parce que .. allumettes. Pour désactiver le dotglob, utilisez shopt -u dotglob ("non défini"). Les modifications sont temporaires cependant, elles ne concernent que le shell actuel. - Lekensteyn
J'ai oublié ça. Y a-t-il un moyen de le définir pour une ligne? quelque chose comme shopt -s dotglob & <grep cmd> & shopt -y dotglobseulement plus pratique? De cette façon, nous n'aurons pas à nous soucier de le réinitialiser - user606723
En outre, il est probablement plus facile à utiliser grep -Rin string . dans la plupart de ces cas. J'utilise juste * parce que cela semble venir plus naturellement. - user606723
Si vous effectuez un grep récursif, vous pouvez simplement commencer par "." au lieu de "*". pas besoin de dotglob. - Michał Šrajer
voter ce, une chose ne mentionne pas dans la page de manuel est R suivra des liens symboliques, r ne fait pas - HVNSweeting


Si vous voulez essayer quelque chose de nouveau, donnez ack un coup de feu. La commande de recherche récursive dans le répertoire en cours pour string est:

ack string

L'installation est assez simple:

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

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


11
2017-08-01 15:09



Ou simplement apt-get install ack-grep (, et ajoutez alias ack = ack-grep à votre .bashrc) - markijbema
Que font les derniers paramètres à la chmod commande faire? Sont-ils spécifiques pour chmod ou sont-ils liés bash (le !#:3 partie)? - Elliott Darfink
@ElliottDarfink C’est en utilisant fonction historique - ! est un désignateur 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. - Konrad Rudolph


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

Si non disponible, vous pouvez l'obtenir comme ça

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

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

Je utilise personnellement

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

sujet connexe: comment toujours utiliser rgrep avec la couleur


3
2018-01-02 13:58



rgrep est fourni par le paquetage grep qui est installé par défaut dans Ubuntu. - karel


Mise à jour 2:

Cette ligne de commandes utilisant find et grep corrige le problème:

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

--color=<always or auto> pour sortie colorée:

$ 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 .bashrcou .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
}

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

Exemple:

$ wherein ~/Documents/ "hello world"

(Remarque: Comme suggéré dans les commentaires ci-dessous par @enzotib, cela ne fonctionne pas avec les fichiers / répertoires, y compris les espaces dans leurs noms.)


Poste d'origine

Pour rechercher la chaîne et sortir 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 du 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
2018-01-25 11:11



Échoue sur les noms de fichiers contenant des espaces. Le défaut est caché par le fait que stderr n'est pas montré. - enzotib
@enzotib merci de le signaler .. ce n'est toujours pas résolu pour la fonction spécifiée .. J'ai ajouté un autre one-liner si .. - precise
Maintenant, la réponse est similaire à celle de @dmityugov. - enzotib
oui, mais en ce sens la plupart des réponses sur cette page si vous vérifiez sont similaires en ce qui concerne leur utilisation grep, à côté de cela le sous-ensemble utilisant find avec grep... mais si vous devez accepter différents changements et réglages comme réponse distincte, le mien sera probablement aussi ici. la dernière mise à jour fait ce que je voudrais dans ma recherche: noms de fichiers avec des lignes avec la clé de recherche et la ligne no. aussi :) et sortie colorée et filtre d'erreur pour une meilleure lisibilité .. - precise