Comment rechercher du texte dans tout le système de fichiers?

53

En supposant que l'outil grep soit utilisé, j'aimerais rechercher la chaîne de texte "800x600" dans tout le système de fichiers.

J'ai essayé:

grep -r 800x600 /

mais ça ne marche pas.

Ce que je crois que ma commande devrait faire, c’est grep de manière récursive dans tous les fichiers / dossiers de la racine du texte "800x600" et répertorier les résultats de la recherche.

Qu'est-ce que je fais mal?

Level1Coder
la source
2
Et par "ça ne marche pas" tu veux dire exactement quoi? N'imprime-t-il aucune sortie, ne se bloque ou n'imprime pas beaucoup d' Permission deniederreurs? L'avez-vous exécuté en tant qu'utilisateur root ou utilisateur normal?
alex
Je reçois un peu de traction, tout d’abord, je me trouvais dans mon répertoire personnel d’utilisateur à essayer d’exécuter la commande. Alors maintenant, j'ai cd / out à la racine. Ensuite, j'ai essayé la même commande que ci-dessus et je reçois beaucoup d'erreurs de permission refusée. Ok, alors maintenant j'essaie sudo grep -r 800x600 / et puis j'obtiens un / proc / sysrq-trigger: Erreur entrée / sortie
Level1Coder
Hmm, je ne sais pas pourquoi cela ne fonctionnerait pas. Vous pouvez ignorer les erreurs d'accès en le faisant grep -r 800x600 / 2>/dev/null. Vous pouvez également essayer de l'exécuter en tant que root.
Totor

Réponses:

64

J'utilise normalement ce style de commande pour exécuter grepplusieurs fichiers:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

Cela permet en réalité de répertorier tous les fichiers du système, puis de les exécuter grepavec les arguments donnés et le nom de chaque fichier.

L' -xdevargument indique à find qu'il doit ignorer les autres systèmes de fichiers, ce qui permet d'éviter des systèmes de fichiers spéciaux tels que /proc. Cependant, il ignorera également les systèmes de fichiers normaux. Ainsi, si, par exemple, votre dossier / home est sur une partition différente, la recherche ne sera pas effectuée, vous devrez le préciser find / /home -xdev ....

-type fsignifie que la recherche de fichiers uniquement, ainsi les répertoires, les périphériques et autres fichiers spéciaux sont ignorés (il restera toujours dans les répertoires et sera exécuté grepsur les fichiers qu'il contient - il ne sera tout simplement pas exécuté grepsur le répertoire lui-même, ce qui ne fonctionnerait pas de toute façon). Et l' -Hoption lui grepdit de toujours imprimer le nom du fichier dans sa sortie.

findaccepte toutes sortes d’options pour filtrer la liste des fichiers. Par exemple, -name '*.txt'traite uniquement les fichiers se terminant par .txt. -size -2Msignifie que les fichiers sont plus petits que 2 mégaoctets. -mtime -5signifie les fichiers modifiés au cours des cinq derniers jours. Joignez-les avec -a pour et et -o pour ou , et utilisez des '('parenthèses ')'pour regrouper les expressions (entre guillemets pour empêcher le shell de les interpréter). Donc par exemple:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

Consultez man findla liste complète des filtres possibles.

Richard Downer
la source
2
Notez que -xdevcela exclura tous les autres systèmes de fichiers, pas seulement les spéciaux. (par exemple, si vous avez /homemonté une partition séparée, la recherche ne sera pas effectuée.)
cjm
J'ai essayé de les exécuter mais les deux retournent une erreur -find: paths must precede expression: /
Level1Coder
1
Remarque: lorsque les expressions régulières ne sont pas requises, "fgrep" est nettement plus rapide que "grep", ce qui aura une grande incidence si vous recherchez un grand arbre.
Nathan Kidd
1
Vous pouvez éviter d’agir xargsavec peut-être une plus grande efficacité en agissant find / -xdev -type f -exec grep -H '800x600' +.
Totor
3
Non, le +signe à la fin de la findcommande fait la même chose que xargs: il génère un grepprocessus avec plusieurs arguments.
Totor
14

Normalement, vous ne voudriez pas réellement rechercher TOUT sur le système. Linux utilise pour tout le contenu des nœuds de fichiers, de sorte que certains "fichiers" ne sont pas des objets dans lesquels vous souhaitez effectuer une recherche. Par exemple, /dev/sdale périphérique de blocage physique de votre premier disque dur. Vous souhaiterez probablement effectuer une recherche dans les systèmes de fichiers montés et non dans le périphérique de disque brut. En outre, il existe /dev/randomdes données aléatoires à chaque fois que vous les lisez. Rechercher cela n'a pas beaucoup de sens. Le /procsystème de fichiers est également problématique dans votre cas.

Je recommanderais l'une des deux choses.

  1. Ne cherchez pas à la racine, cherchez seulement les endroits qui pourraient vous être utiles. Rechercher /homeou /usrou /etcséparément. Les informations que vous recherchez sont susceptibles d'un type spécifique, elles sont donc susceptibles de se trouver dans un dossier spécifique. Les paramètres de configuration doivent être dans /etc. Vos fichiers de données personnelles doivent être dans /home. En limitant la recherche à un domaine majeur comme celui-ci, vous réduirez considérablement vos problèmes avec les greps récursifs.

  2. Excluez les zones problématiques en utilisant --exclude-diret un ensemble de choses que vous savez dont vous n’avez pas besoin, comme ceci:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

Enfin, il n'est pas rare de rencontrer quelques erreurs de type «autorisation refusée» lors de l'exécution d'un grand grep récursif. Dans le cours normal de l’utilisation, il est possible que certains utilisateurs ne puissent pas lire certains fichiers. Tant qu'il ne s'agit que de quelques fichiers impairs et non d'éléments comme le périphérique brut de vos disques durs ou l'ensemble du système de fichiers proc, vous pouvez ignorer simplement les erreurs. En fait, vous pouvez le faire sur la ligne de commande en envoyant toutes les erreurs dans Never Never Never:

grep -r search_string /path 2> /dev/null
Caleb
la source
3
-Iexclure les binaires
Rahul Patil
2

Pour plus de simplicité, je suggérerais ack-grep . Le lien montre de nombreux cas où ack-grepest une meilleure option.

Pour utiliser est, après l'installation:

ack-grep pattern /
bbaja42
la source
Merci d'avoir recommandé cela, mais je l'ai exécuté et cela ne m'a pas vraiment donné les résultats de recherche prévus. On dirait que je devrai modifier de nombreux paramètres pour obtenir ce que je veux. A partir de maintenant, la réponse de Richard fonctionne immédiatement. Nous examinerons cela à l'avenir, car cela semble également utile.
Level1Coder
1

Une autre façon de voir les choses est la suivante:

grep -r /* | grep "800x600"
maniat1k
la source
0

* alors j'obtiens un / proc / sysrq-trigger: erreur d'entrée / sortie

Votre commande fonctionne, vous obtenez cette erreur car vous essayez d'analyser les processus en cours pour rechercher une chaîne.

Je recommande d'exclure les répertoires système avec

grep -exclude-dir = {proc, sys} "800x600" /

Koffee
la source
-3

tout simplement à droite

grep -r "800x600" /

-Quel est le problème dans votre commande actuelle, les guillemets, "". Toujours mettre l'argument de chaîne grepentre guillemets.

Amita
la source
3
Ce n'est pas le problème ici. Vous n'avez pas besoin de guillemets pour donner ce type d'argument à grep. Essayez et vous verrez. Placez la chaîne "800x600" dans un fichier, puis grep 800x600 filevous verrez que cela fonctionne correctement. Le PO a évidemment un autre problème.
slm