Recherche de fichiers contenant une certaine chaîne à l'aide de find (1) et de grep (1)

70

find . -type f -print -exec cat {} \; | grep some string

La commande ci-dessus n'imprime pas le chemin du fichier.

J'utilise: Ubuntu, bash 4.

H.Rabiee
la source
Peut-être que cela ne répond pas à vos résultats escomptés à cause du filtre grep. Qu'en est-il:find . -type f -fprint /dev/stderr -exec cat {} \; | grep some string
artistoex le
Quel est le but que vous souhaitez atteindre? Sur la sortie, vous obtenez des chaînes de texte recouvertes, vous voulez le chemin de ces fichiers?
mirkobrankovic
Oui, je veux imprimer le chemin des fichiers contenant la chaîne 'une chaîne'. La suggestion de @artistoex imprime tous les chemins de fichiers.
H.Rabiee
Vous voudrez peut-être simplement utiliser ackpour grep tous les fichiers du répertoire en cours, en filtrant éventuellement sur certains types de fichiers uniquement.
Jaap Eldering

Réponses:

87

En effet, vous alimentez grepun flux de texte contenant des noms de fichiers. Puisque vous n’avez fourni aucun nom de fichier en tant qu’argument à grep, vous ne pouvez pas en déduire de quel fichier provient une ligne correspondante. Utiliser xargs:

find . -type f -print | xargs grep "some string"

Puisque vous avez GNU find / xargs, c’est un moyen plus sûr pour xargs de lire les noms de fichiers:

find . -type f -print0 | xargs -0 grep "some string"

Si vous voulez seulement les noms de fichiers qui ont une ligne correspondante sans afficher la ligne correspondante:

find . -type f -print0 | xargs -0 grep -l "some string"
Glenn Jackman
la source
Comment combiner les commandes ci-dessus avec search & replace? En tant que, grep then sed?
CMCDragonkai
1
les noms de fichiers de sortie du pipeline find | grep, donc:sed '...' $(find ... | xargs grep -l ...)
glenn jackman
107

j'utilise

grep "some string" . -R

et ça marche plus vite

ps

Cas d'utilisation plus complexe

grep -HiRE "some string|other string" . #H for file printing, i for case-insensitive, R for recursive search, E for regex 

Pour lire l'explication param i

grep --help | grep -- -i
ArcherGodson
la source
17
Et -nsi vous voulez des numéros de ligne. +1 pour une réponse simplifiée.
Chad Skeeters
@ChadSkeeters exactement. Utiliser la découverte ne donne pas une telle solution.
ArcherGodson
1
Cela devrait être marqué comme la bonne réponse, pour être honnête. Celui qui est actuellement sélectionné détaille autre chose.
12

Je recherche souvent le code source dans des structures de dossiers complexes et je trouve utile d'utiliser:

cd /your/folder/
grep -rHino "your string"

Avec ces paramètres, sans utiliser find , j'obtiens le chemin complet du fichier et le numéro de ligne qui contient la chaîne spécifiée .

Il est également facile de se rappeler parce qu'il BASH es par votre recherche comme un RHINO :)

Je vais montrer comment cela fonctionne avec un exemple rapide.

Affiche le contenu d'un fichier en utilisant cat:

jeeves ~ # cat fw.stop
#!/bin/sh
echo "Stopping firewall and allowing everyone..."
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Et cherchons récursivement tous les fichiers contenant la chaîne "iptables -P":

jeeves ~ # grep -rinHo "iptables -P"
fw.stop:9:iptables -P
fw.stop:10:iptables -P
fw.stop:11:iptables -P

Comme vous pouvez le voir dans le résultat, nous avons filename: hit row: chaîne recherchée

Voici une description plus détaillée des paramètres utilisés:

-r Pour chaque opérande de répertoire, lisez et traitez tous les fichiers de ce répertoire de manière récursive. Suivez les liens symboliques sur la ligne de commande, mais ignorez les liens symboliques rencontrés de manière récursive. Notez que si aucun opérande de fichier n’est donné, grep cherche dans le répertoire de travail. C'est la même chose que l'option '--directories = recurse'.

-i Affiche le nom du fichier pour chaque correspondance. C'est la valeur par défaut lorsqu'il y a plus d'un fichier à rechercher.

-n Préfixe chaque ligne de sortie avec le numéro de ligne basé sur 1 dans son fichier d'entrée. (-n est spécifié par POSIX.)

-H Affiche le nom du fichier pour chaque correspondance. C'est la valeur par défaut lorsqu'il y a plus d'un fichier à rechercher.

-o Imprimez uniquement les parties correspondantes (non vides) des lignes correspondantes, chacune de ces parties se trouvant sur une ligne de sortie distincte. Les lignes de sortie utilisent les mêmes délimiteurs comme entrée et les délimiteurs sont des octets nuls si -z (--null-data) est également utilisé (voir Autres options).

Pitto
la source
2

J'ai preferé

| trouver le fichier | make grep ont trouver le fichier | affiche le chemin complet du fichier

find / -type f -exec grep 'une chaîne' {} \; -exec echo {} \;

utilisateur515185
la source
0

Silver Searcher est un utilitaire très rapide et pratique pour rechercher des fichiers et du contenu.

Pour résoudre votre problème, la commande Silver Searcher ressemblerait à ceci ...

ag 'some string' -l

-l Imprimer uniquement les noms de fichiers contenant des correspondances (ne pas imprimer les lignes correspondantes)

qoomon
la source