web-dev-qa-db-fra.com

Comment trouver tous les fichiers contenant du texte spécifique sur Linux?

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

Lorsque je cherchais comment faire cela, je suis tombé sur cette solution à deux reprises:

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

Cependant, ça ne marche pas. Il semble afficher chaque fichier du système.

Est-ce proche de la bonne façon de le faire? Si non, comment devrais-je? Cette capacité à rechercher des chaînes de texte dans des fichiers serait extrêmement utile pour certains projets de programmation que je réalise.

4457
Nathan

Faites ce qui suit:

grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -r ou -R est récursif,
  • -n est le numéro de ligne, et
  • -w signifie correspondre à tout le mot.
  • -l (L minuscule) peut être ajouté pour simplement donner le nom de fichier des fichiers correspondants.

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

  • Cela recherchera uniquement dans les fichiers portant les extensions .c ou .h:

    grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
    
  • Cela exclura la recherche dans 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 des répertoires particuliers via le paramètre --exclude-dir. Par exemple, cela exclura les répertoires dir1 /, dir2/et tous ceux-ci correspondant à * .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.

8076
rakib_

Vous pouvez utiliser grep -ilR:

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

Vous pouvez utiliser ack . C'est comme grep pour le code source. Vous pouvez analyser tout votre système de fichiers avec.

Il suffit de faire:

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 The Silver Searcher , qui ressemble à ack mais 3-5x plus rapide qu’elle et ignore même les motifs d’un fichier .gitignore.

283
EarlOfEgo

Vous pouvez utiliser:

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

La r signifie récursif et va donc chercher dans le chemin spécifié ainsi que dans ses sous-répertoires. Cela vous indiquera le nom du fichier et imprimera la ligne dans le 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 dans les fichiers où le texte apparaît, mais n'imprimera pas le nom du fichier.

En plus de cette commande, nous pouvons également écrire ceci: grep -rn "Chaîne de recherche"/chemin/dans/répertoire/ou/fichier -r: recherche récursive n: le numéro de ligne sera indiqué pour les correspondances

156
learner_19

Vous pouvez utiliser ceci:

grep -inr "Text" folder/to/be/searched/
98
A R

Liste des noms de fichiers contenant un texte donné

Tout d’abord, je pense que vous avez utilisé -H au lieu de -l. Vous pouvez également essayer d’ajouter le texte entre guillemets suivi de {} \.

find / -type f -exec grep -l "text-to-find-here" {} \; 

Exemple

Supposons que vous recherchiez des fichiers contenant du texte spécifique "Licence Apache" dans votre répertoire. Il affichera des résultats similaires à ceux présentés ci-dessous (la sortie sera différente en fonction du contenu de votre répertoire).

bash-4.1$ find . -type f -exec grep -l "Apache License" {} \; 
./net/Java/jvnet-parent/5/jvnet-parent-5.pom
./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom
./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom
./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom
./commons-codec/commons-codec/1.9/commons-codec-1.9.pom
./commons-io/commons-io/2.4/commons-io-2.4.pom
bash-4.1$ 

Supprimer la sensibilité à la casse

Même si vous n'êtes pas habitué à la casse comme "texte" ou "TEXT", vous pouvez utiliser le commutateur -i pour ignorer la casse. Vous pouvez lire plus de détails ici .

J'espère que cela vous aide.

59
lkamal

Si votre grep ne prend pas en charge la recherche récursive, vous pouvez combiner find avec xargs:

find / -type f | xargs grep 'text-to-find-here'

Je trouve cela plus facile à retenir que le format pour find -exec.

Cela produira le nom de fichier et le contenu de la ligne correspondante, par exemple.

/home/rob/file:text-to-find-here

Drapeaux facultatifs que vous voudrez peut-être ajouter à grep:

  • -i - recherche insensible à la casse
  • -l - n'indique que le nom du fichier où la correspondance a été trouvée
  • -h - affiche uniquement la ligne qui correspond (pas le nom du fichier)
51
RobEarl

(grep ( GNU ou BSD )

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

grep -r "class foo" .

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

Vous pouvez également utiliser la syntaxe de globbing pour rechercher dans des fichiers spécifiques tels que:

grep "class foo" **/*.c

Remarque: En utilisant option de suppression } _ (**), 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 réduire 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 des fichiers volumineux, vous devriez plutôt utiliser ripgrep, comme:

rg "class foo" .

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 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 - Affiche 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.
50
kenorb
grep -insr "pattern" *
  • i: Ignore les différences de casse dans les fichiers PATTERN et les fichiers d'entrée.
  • n: préfixez chaque ligne de sortie avec le numéro de ligne basé sur 1 dans son fichier d'entrée.
  • s: Supprime les messages d'erreur concernant les fichiers inexistants ou illisibles.
  • r: lit tous les fichiers de chaque répertoire de manière récursive.
38
enfinet

Essayer:

find . -name "*.txt" | xargs grep -i "text_pattern"
27
venkat

Comment trouver tous les fichiers contenant du texte spécifique sur Linux? (...)

Je suis tombé sur cette solution deux fois:

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


Si vous utilisezfindcomme dans votre exemple, il vaut mieux ajouter -s (--no-messages) à grep et 2>/dev/null à la fin de la commande pour éviter de nombreux Autorisation refusée émises par grep et find:

find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null

findest l'outil standard de recherche de fichiers, associé à grep lors de la recherche de texte spécifique, sur des plates-formes de type Unix. La commande find est souvent combinée avec xargs , d'ailleurs.

Des outils plus rapides et plus simples existent dans le même but - voir ci-dessous. Mieux vaut les essayer, à condition qu'elles soient disponibles sur votre plate-forme}, bien sûr:

Des alternatives plus rapides et plus faciles

RipGrep- l'outil de recherche le plus rapide autour de:

rg 'text-to-find-here' / -l

Le chercheur d'argent:

ag 'text-to-find-here' / -l

ack:

ack 'text-to-find-here' / -l

Remarque: Vous pouvez également ajouter 2>/dev/null à ces commandes pour masquer de nombreux messages d'erreur.


Warning : sauf si vous ne pouvez vraiment pas l'éviter, ne cherchez pas dans '/' (le répertoire racine) pour éviter une recherche longue et inefficace. ! Ainsi, dans les exemples ci-dessus, vous feriez mieux de remplacer '/' par un nom de sous-répertoire, par exemple "/ home" en fonction de l'endroit où vous souhaitez effectuer la recherche ...

27
Bludzee

Il y a un nouvel utilitaire appelé The Silversearcher

Sudo apt install silversearcher-ag

Il travaille en étroite collaboration avec Git et d’autres VCS. Donc, vous n'obtiendrez rien dans un .git ou un autre répertoire.

Vous pouvez simplement utiliser

ag -ia "Search query"

Et cela fera le travail pour vous!

27
Neil Agarwal

Utilisez pwd pour effectuer une recherche à partir de n'importe quel répertoire, récursif vers le bas

grep -rnw `pwd` -e "pattern"

Mise à jour Selon la version de grep que vous utilisez, vous pouvez omettre pwd. Sur les versions plus récentes, . semble être le cas par défaut pour grep si aucun répertoire n'est donné, ainsi:

grep -rnw -e "pattern"

ou

grep -rnw "pattern"

fera la même chose que ci-dessus!

26
mahatmanich

grep peut être utilisé même si nous ne cherchons pas de chaîne.

Simplement en cours d'exécution,

grep -RIl "" .

affichera le chemin de tous les fichiers texte, c’est-à-dire ceux qui ne contiennent que des caractères imprimables.

18
Alex Jasmin

Voici la liste de plusieurs commandes pouvant être utilisées pour rechercher un fichier.

grep "text string to search” directory-path

grep [option] "text string to search” directory-path

grep -r "text string to search” directory-path

grep -r -H "text string to search” directory-path

egrep -R "Word-1|Word-2” directory-path

egrep -w -R "Word-1|Word-2” directory-path
16
Atul Arvind

Un find simple peut être pratique. alias le dans votre fichier ~/.bashrc:

alias ffind find / -type f | xargs grep

Démarrer un nouveau terminal et émettre:

ffind 'text-to-find-here'
14
danglingpointer
find /path -type f -exec grep -l "string" {} \;

Explication des 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 specifies that it should proceed only files, not directories etc.
-exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename
14
Vinod Joshi

J'espère que c'est utile ...

Développer un peu grep pour donner plus d'informations dans la sortie, par exemple, pour obtenir le numéro de ligne dans le fichier contenant le texte, procédez comme suit:

find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"

Et si vous avez une idée du type de fichier, vous pouvez affiner votre recherche en spécifiant les extensions de type de fichier à rechercher, dans ce cas, .pas OR .dfm:

find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"

Brève explication des options:

  1. . dans la find spécifie à partir du répertoire en cours.
  2. -name "*.*": pour tous les fichiers (-name "*.pas" -o -name "*.dfm"): uniquement les fichiers *.pas OR *.dfm, OR spécifiés avec -o
  3. -type f indique que vous recherchez des fichiers
  4. -print0 et --null de l’autre côté du | (canal) sont les plus importants, en passant le nom de fichier de la variable find à la variable grep incluse dans la variable xargs, permettant ainsi de transmettre les noms de fichiers AVEC des espaces dans les noms de fichiers, ce qui permet à grep de traiter le chemin. et nom de fichier comme une chaîne, et ne pas le casser sur chaque espace.
14
Gert van Biljon

Silver Searcher est un outil formidable, mais ripgrep peut être encore meilleur.

Il fonctionne sous Linux, Mac et Windows, et a été écrit sur Hacker News il y a quelques mois (il y a un lien vers le blog d'Andrew Gallant qui contient un lien GitHub):

Ripgrep - Un nouvel outil de recherche en ligne de commande

14
AAAfarmclub

Essayer:

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

qui recherchera tous les systèmes de fichiers, car / est le dossier racine.

Pour les dossiers personnels, utilisez:

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

Pour le dossier actuel, utilisez:

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

J'ai écrit un script Python qui fait quelque chose de similaire. Voici comment utiliser ce script.

./sniff.py path pattern_to_search [file_pattern]

Le premier argument, path, est le répertoire dans lequel nous effectuerons une recherche récursive. Le deuxième argument, pattern_to_search, est une expression régulière que nous souhaitons rechercher dans un fichier. Nous utilisons le format d'expression régulière défini dans la bibliothèque Pythonre. Dans ce script, le . correspond également à la nouvelle ligne.

Le troisième argument, file_pattern, est facultatif. Ceci est une autre expression régulière qui fonctionne sur un nom de fichier. Seuls les fichiers correspondant à cette expression régulière seront pris en compte.

Par exemple, si je veux rechercher des fichiers Python avec l'extension py contenant Pool( suivie de Word Adaptor, je fais ce qui suit:

./sniff.py . "Pool(.*?Adaptor"  .*py
./Demos/snippets/cubeMeshSigNeur.py:146 
./Demos/snippets/testSigNeur.py:259 
./python/moose/multiscale/core/mumbl.py:206 
./Demos/snippets/multiComptSigNeur.py:268 

Et voila, il génère le chemin des fichiers correspondants et le numéro de la ligne à laquelle la correspondance a été trouvée. Si plusieurs correspondances ont été trouvées, chaque numéro de ligne sera ajouté au nom du fichier.

13
Dilawar

Utilisation:

grep -c Your_Pattern *

Cela indiquera le nombre de copies de votre modèle dans chacun des fichiers du répertoire actuel.

12
Dr_Hope

grep est votre bon ami pour y parvenir.

grep -r <text_fo_find> <directory>

si vous ne vous souciez pas de la casse du texte à trouver, utilisez

grep -ir <text_to_find> <directory>
11
Prash

Toutes les réponses précédentes suggèrent grep et find. Mais il existe un autre moyen: Utilisez Midnight Commander

C'est un utilitaire gratuit (30 ans, prouvé par le temps) qui est visuel sans être une interface graphique. Il a des tonnes de fonctions et la recherche de fichiers n’est que l’une d’elles.

11
Peter M.

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;
11
user3124504

Il existe un outil ack qui ferait exactement ce que vous recherchez.

http://linux.die.net/man/1/ack

ack -i search_string folder_path/*

Vous pouvez ignorer -i pour la recherche sensible à la casse

11
Pal

La commande ci-dessous fonctionnera correctement pour cette approche:

find ./ -name "file_pattern_name"  -exec grep -r "pattern" {} \;
10
Pradeep Goswami

Essaye ça:

find . | xargs grep 'Word' -sl
10
Tayab Hussain

Je suis fasciné par la facilité avec laquelle grep le fait avec 'rl'

grep -rl 'pattern_to_find' /path/where/to/find

-r to find recursively file / directory inside directories..
-l to list files matching the 'pattern'

Utilisez '-r' sans 'l' pour voir les noms de fichiers suivis de texte dans lequel se trouve le motif !

grep -r 'pattern_to_find' /path/where/to/find

Fonctionne tout simplement parfait ..

J'espère que ça aide!

10
nitinr708

Vous pouvez utiliser la commande ci-dessous car vous ne voulez pas de nom de fichier, mais vous souhaitez effectuer une recherche dans tous les fichiers. Voici que je capture le formulaire "TEXT" Tous les fichiers journaux en s'assurant que le nom du fichier n’est pas imprimé

grep -e TEXT *.log | cut -d' ' --complement -s -f1

grep avec l'option -e est assez rapide comparé à une autre option comme c'est le cas pour le match PATTERN

10
Mitul Patel

Évitez les tracas et installez ack-grep. Cela élimine beaucoup de problèmes de permission et de citation.

apt-get install ack-grep

Ensuite, allez dans le répertoire que vous souhaitez rechercher et exécutez la commande ci-dessous

cd /
ack-grep "find my keyword"
10
Kareem

find avec xargs est préférable quand il y a beaucoup de correspondances potentielles à parcourir. Il fonctionne plus lentement que les autres options, mais cela fonctionne toujours. Comme certains l’ont découvert, xargs ne gère pas les fichiers contenant des espaces incorporés par défaut. Vous pouvez résoudre ce problème en spécifiant l'option -d.

Voici la réponse de @ RobEarl, améliorée afin de traiter les fichiers avec des espaces:

find / -type f | xargs -d '\n' grep 'text-to-find-here'

Voici la réponse de @ venkat, améliorée de manière similaire:

find . -name "*.txt" | xargs -d '\n' grep -i "text_pattern"

Voici la réponse de @Gert van Biljon, améliorée de la même manière:

find . -type f -name "*.*" -print0 | xargs -d '\n' --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"

Voici la réponse de @ LetalProgrammer, améliorée de la même manière:

alias ffind find / -type f | xargs -d '\n' grep

Voici la réponse de @Tayab Hussain, améliorée de la même manière:

find . | xargs -d '\n' grep 'Word' -sl
7
Mike Slinn

Si vous avez toujours un ensemble de fichiers à vérifier, vous pouvez aliaser leurs chemins, par exemple:

alias fd='find . -type f -regex ".*\.\(inc\|info\|module\|php\|test\|install\|uninstall\)"'

Ensuite, vous pouvez simplement filtrer la liste comme ceci:

grep -U -l $'\015' $(fd)

Ce qui filtre la liste fd aux fichiers contenant le modèle CR.

Je trouve qu'aliaser les fichiers qui m'intéressent m'aide à créer des scripts plus faciles, puis à essayer de se rappeler comment obtenir tous ces fichiers. Les opérations récursives fonctionnent également, mais tôt ou tard, vous devrez vous débarrasser de certains types de fichiers. C'est pourquoi je trouve juste tous les types de fichiers qui m'intéressent.

7
dkinzer

Si vous voulez strictement utiliser find, alors:

find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;

find + grep

1.Utilisez find pour rechercher des fichiers, 2.Puis exécutez grep sur chacun d'entre eux.

Peut être combiné en une commande comme ci-dessous:

find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;

  • Utilisez -name Pattern si vous voulez grep uniquement certains fichiers:

    find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;

Cela peut vous donner le pouvoir de find de trouver des fichiers. Vous pouvez y jouer et utiliser différentes options de find pour améliorer ou affiner votre recherche de fichiers.

7
BreakBadSP

Essaye ça:

find / -type f -name "*" -exec grep -il "String_to_search" {} \;

Ou

for i in /*;do grep -Ril "String_to_search" $i;done 2> /dev/null
7
VIPIN KUMAR

Utilisation:

grep -Erni + "text you wanna search"

La commande effectuera une recherche récursive dans tous les fichiers et répertoires du répertoire actuel et imprimera le résultat.

Remarque: si votre sortie grep n'est pas colorée, vous pouvez la changer en utilisant l'alias grep = 'grep --color = always' dans votre fichier source Shell.

7
baldash

Vous pouvez utiliser les commandes suivantes pour rechercher du texte particulier dans un fichier:

cat file | grep 'abc' | cut -d':' -f2
7
iamjayp

Comme Peter dans la réponse précédente , toutes les réponses précédentes suggèrent grep et find.

Mais il existe un moyen plus sophistiqué d’utiliser Gnome Commander avec unGUIparfait et avec des tonnes d’options depuis 2001, et la recherche de fichiers n’est que l’une d’elles. C'est aussi un utilitaire gratuit, prouvé par le temps.

7
Geeocode

Essaye ça

find . -type f -name some_file_name.xml -exec grep -H PUT_YOUR_STRING_HERE {} \;
6
Sireesh Yarlagadda

Voir aussi The Platinum Searcher , qui est similaire à The Silver Searcher et écrit en Go.

Exemple:

pt -e 'text to search'
5
Gustavo Paulo

Alternative de recherche dans l'interface graphique - Usage pour le bureau:

_ {- Comme la question ne demande pas précisément des commandes} _

Searchmonkey : Outil de recherche de fichier avancé sans avoir à indexer votre système à l'aide d'expressions régulières. Équivalent graphique pour trouver/grep. Disponible pour Linux (Gnome/KDE/Java) et Windows (Java) - GPL open source GPL v3

Caractéristiques:

  • Expressions régulières avancées
  • Résultats affichés dans le contexte
  • Recherche contenant du texte
  • Panneau pour afficher la ligne contenant du texte
  • Nouvelles mises à jour 2018
  • etc.

Téléchargement - Liens:

.

Capture d'écran:

 Enter image description here

5
intika

votre commande est correcte. Juste besoin d'ajouter -l à grep.

find / -type f -exec grep -l 'text-to-find-here' {} \;
0
FariZ