6323 votes

Comment trouver tous les fichiers contenant un texte spécifique sous Linux ?

J'essaie de trouver un moyen d'analyser tout mon système Linux pour trouver tous les fichiers contenant une chaîne de texte spécifique. Pour clarifier, je cherche du texte dans le fichier, pas dans le nom du fichier.

En cherchant comment faire, je suis tombé deux fois sur cette solution :

find / -type f -exec grep -H 'text-to-find-here' {} \;

Cependant, cela ne fonctionne pas. Il semble afficher tous les fichiers du système.

Est-ce que c'est proche de la bonne façon de faire ? Si non, comment dois-je faire ? Cette capacité à trouver des chaînes de texte dans des fichiers serait extraordinairement utile pour certains projets de programmation que je réalise.

34 votes

Rappelez-vous que grep interprétera toute . comme un caractère de remplacement à un seul caractère, entre autres. Mon conseil est de toujours utiliser soit fgrep soit egrep.

12 votes

De toute façon, vous y étiez presque ! Remplacez simplement -H con -l (et peut-être grep con fgrep ). Pour exclure les fichiers avec certains modèles de noms, vous pouvez utiliser find de manière plus avancée. Il vaut la peine d'apprendre à utiliser les outils suivants find mais Juste man find .

8 votes

find … -exec <cmd> + est plus facile à taper et plus rapide que find … -exec <cmd> \; . Il ne fonctionne que si <cmd> accepte un nombre quelconque d'arguments pour le nom du fichier. L'économie en temps d'exécution est particulièrement importante si <cmd> est lent à démarrer comme les scripts de Python ou de Ruby.

11591voto

rakib Points 6571

Faites ce qui suit :

grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -r o -R est récursif,
  • -n est le numéro de la ligne, et
  • -w correspond au mot entier.
  • -l (L minuscule) peut être ajouté pour donner simplement le nom de fichier des fichiers correspondants.
  • -e est le modèle utilisé pendant la recherche

En plus de ceux-ci, --exclude , --include , --exclude-dir pourraient être utilisés pour une recherche efficace :

  • Cette recherche ne portera que sur les fichiers dont l'extension est .c ou .h :

    grep --include=*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"

  • Cela exclura la recherche de tous les fichiers se terminant par l'extension .o :

    grep --exclude=*.o -rnw '/path/to/somewhere/' -e "pattern"

  • Pour les répertoires, il est possible d'exclure un ou plusieurs répertoires à l'aide de la commande --exclude-dir paramètre. Par exemple, cela exclura les répertoires dir1/, dir2/ et tous ceux qui correspondent à *.dst/ :

    grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"

Cela fonctionne très bien pour moi, pour atteindre presque le même objectif que le vôtre.

Pour plus d'options, consultez man grep .

2 votes

Mais comment faire pour qu'il ignore les fichiers binaires ?

87 votes

Utilisez --exclude. comme "grep -rnw --exclude=*.o 'directory' -e "pattern"".

0 votes

Si cela ne fonctionne pas, supprimez le répertoire. De plus, si le répertoire est volumineux, il se peut qu'il se bloque pendant une seconde. Ce n'est pas instantané.

1822voto

fedorqui Points 42938

Vous pouvez utiliser grep -ilR :

grep -Ril "text-to-find-here" /
  • i signifie ignorer le cas (facultatif dans votre cas).
  • R signifie "récursif".
  • l signifie "montrer le nom du fichier, pas le résultat lui-même".
  • / signifie que vous devez commencer à la racine de votre machine.

0 votes

Combien de temps en moyenne (cela dépend évidemment beaucoup du système) pensez-vous qu'il faudrait pour analyser l'ensemble du système ? Pensez-vous que l'utilisation d'une expression régulière avec grep permettrait d'aller plus vite ?

108 votes

D'après mon expérience, le -i le rend très lent, donc ne l'utilisez pas si ce n'est pas nécessaire. Testez-le dans un certain domaine, puis généralisez. Cela devrait être fait en quelques minutes. Je pense qu'une expression régulière le rendrait plus lent. Mais mes commentaires sont basés sur des suppositions, je vous suggère de le tester avec time devant la ligne.

5 votes

Oui, /* représente cela. Bref, je viens de le tester et j'ai remarqué que juste / travaux.

392voto

EarlOfEgo Points 1480

Vous pouvez utiliser ack . C'est comme grep pour le code source. Il vous permet d'analyser l'ensemble de votre système de fichiers.

Fais-le :

ack 'text-to-find-here'

Dans votre répertoire racine.

Vous pouvez également utiliser expressions régulières spécifier le type de fichier, etc.


UPDATE

Je viens de découvrir Le chercheur d'argent qui est comme ack mais 3-5x plus rapide que lui et qui ignore même les motifs d'un .gitignore fichier.

68 votes

Très utile, simple et rapide. Avertissement : "Sur les distros dérivées de Debian, ack est empaqueté sous le nom de "ack-grep" car "ack" existait déjà" (de beyondgrep.com/installation ). Vous pourriez finir par utiliser un convertisseur de code Kanji sur ces Linux...

11 votes

Ack ou ack-grep a de bons résultats, mais find+grep, lorsqu'il est bien utilisé, est bien plus performant.

26 votes

Notez que ripgrep est plus rapide que tout ce qui est mentionné ici, y compris The Silver Searcher et le bon vieux grep. Voir cet article de blog pour preuve.

241voto

learner_19 Points 289

Vous pouvez utiliser :

grep -r "string to be searched"  /path/to/dir

El r signifie récursif, ce qui signifie que la recherche s'effectuera dans le chemin spécifié et dans ses sous-répertoires. Cela vous indiquera le nom du fichier et imprimera la ligne du fichier où la chaîne apparaît.

Ou une commande similaire à celle que vous essayez (exemple : ) pour rechercher dans tous les fichiers javascript (*.js) :

find . -name '*.js' -exec grep -i 'string to search for' {} \; -print

Cela imprimera les lignes des fichiers où le texte apparaît, mais pas le nom du fichier.

En plus de cette commande, nous pouvons aussi écrire ceci : grep -rn "Chaîne à rechercher" /path/to/directory/or/file -r : recherche récursive n : le numéro de ligne sera affiché pour les correspondances

1 votes

Merci pour la version trouvée. Ma version grep (busybox pour NAS) n'a pas l'option -r, j'avais vraiment besoin d'une autre solution !

3 votes

Merci pour la version " découverte " ! C'est tellement important de pouvoir filtrer par " ". .js' ou ' .txt', etc. Personne ne veut passer des heures à attendre que grep finisse de chercher toutes les vidéos de plusieurs gigaoctets des dernières vacances en famille, même si la commande est plus facile à taper.

0 votes

Meilleur grep que la version acceptée, car la version acceptée ne recherche pas les demi-mots

138voto

user2599593 Points 138

Vous pouvez utiliser ceci :

grep -inr "Text" folder/to/be/searched/

16 votes

Facile, verbeux, récursif et insensible à la casse. pouces vers le haut.

0 votes

Si vous ajoutez -A3 c'est encore mieux

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X