Wie verwende ich grep, um ALLE Ordner nach Text zu durchsuchen?

Wie verwende ich grep, um ALLE Ordner nach Text zu durchsuchen?

Ich habe Probleme, ALLE Verzeichnisse gleichzeitig mit zu durchsuchen grep. Wenn ich den Befehl verwende:

find . -name "*.txt" | xargs grep texthere

Es dauert einfach ewig und dann bekomme ich die Fehlermeldung „keine solche Datei oder kein solches Verzeichnis“.

Warum passiert das und gibt es nichts Einfacheres als grep? Oder verwende ich den falschen Befehl?

Antwort1

Wenn Sie GNU grep haben, unterstützt grep selbst die Option „-r“ für die rekursive Suche, wie von @Ouroborus vorgeschlagen.

Wenn Ihr grep diese Option leider nicht unterstützt, beispielsweise unter SunOS, können Sie stattdessen die folgenden Befehle verwenden:

find . -name "*.txt" -exec grep -n your_pattern {} /dev/null \;

Der Trick besteht /dev/nulldarin, sicherzustellen, dass bei jeder Ausführung von grep zwei Dateien (die übereinstimmende Datei *.txt und /dev/null) bereitgestellt werden, sodass der Name der gesuchten Dateien gedruckt wird. Außerdem können Sie -type fdie Option hinzufügen find, um den Umfang von einzugrenzen find.

Antwort2

Wie indiese Antwortsind Sie wahrscheinlich besser dran mit:

grep -rnw '/path/to/somewhere/' -e "pattern"

  • -roder -Rrekursiv ist,
  • -nist die Zeilennummer und
  • -wsteht für das ganze Wort.
  • -l(kleines L) kann hinzugefügt werden, um nur die Dateinamen passender Dateien anzugeben.

Antwort3

Wenn Sie Fehlermeldungen bezüglich Berechtigungen erhalten (Sie sagen das nicht), dann vermute ich, dass Sie sich entweder im Stammverzeichnis ( /) oder in einem Pfad befinden, in dem Sie keine Berechtigung zum Lesen aller Dateien haben, wie z. B. in /etcoder in /var. Da Sie aber sagen, dass es furchtbar lange dauert, neige ich eher zur ersten Annahme (dem Stammverzeichnis).

Wenn Sie absolut suchen möchtenalleDateien auf demganzSystem, dann ist das, was Sie tun, ziemlich richtig. EsWilledauert sehr lange, egal was Sie tun. Es sind einfach furchtbar viele Dateien zu durchsuchen.

Sie können verwenden, findum die Anzahl der anzuzeigenden Dateien einzugrenzen.

Im Moment haben Sie

$ find . -name "*.txt" | xargs grep texthere

Da Sie anscheinend nur an einfachen Textdateien interessiert sind, können wir alle anderen Dateitypen (ausführbare Dateien) ausschließen:

$ find / -type f \! -perm -o=x -name "*.txt" | xargs grep texthere

Ich habe es .durch /hier ersetzt, weil ich dortdenkendas sind Sie (korrigieren Sie mich, wenn ich falsch liege). Ich gebe auch an, dass ich möchteDateien( -type f) das sindnicht ausführbar( \! -perm -o=x) ( !muss maskiert werden, damit Ihre Shell keine komischen Dinge damit anstellt).

Nun, es gibt noch ein paar Dinge, die wir tun können. Eines davon ist eine Sicherheitsfrage, und das andere kannmöglicherweisedie Geschwindigkeit ein kleines bisschen verbessern.

Einige Dateinamen enthalten möglicherweise Leerzeichen oder andere seltsame Zeichen, die wir normalerweise nicht in Dateinamen haben möchten. Um diese ordnungsgemäß weitergeben zu können find,grep

$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 grep texthere

Dies ( -print0) bedeutet, dass jeder Dateiname durch ein nulZeichen ( \0) und nicht durch ein Leerzeichen abgegrenzt wird. Und die entsprechende Option zum xargsEmpfangen dieser als nul-abgegrenzten Dateinamen ist -0.

Ich glaube, dass die Fehlermeldung „Keine solche Datei oder kein solches Verzeichnis“ auftritt, weil Sie diese beiden Optionen nicht verwenden.

Die Sache mit der Geschwindigkeit ist fgrep… Dies ist ein Dienstprogramm, das genau dem entspricht, grep -Fdas Sie verwenden sollten, wenn Ihr Suchstring ein einfacher Textstring ohne reguläre Ausdrücke ist.

Wenn Sie also eine reine Textzeichenfolge haben und in jeder einzelnen Datei im gesamten System danach suchen möchten:

$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 fgrep texthere

Die Sache mit den Berechtigungen... Natürlich gibt es Dateien, die Sie nicht lesen können. Sie können entweder findund ausführen, fgrepwobei sudodiesen Dateien Folgendes vorangestellt wird:

$ sudo find ... | xargs -0 sudo fgrep texthere

-permOder Sie könnten versuchen, ein anderes Flag zu erstellen find(und es auch so einzurichten, dass Verzeichnisse ignoriert werden, die Sie nicht betreten können), aber das wäre zu zeitaufwändig und würde zu einer lächerlich langen Befehlszeile führen, deshalb werde ich das hier nicht tun.

Oder Sie könnten sich einfach sudo -seine Root-Shell besorgen und das Ding von dort aus ausführen ... aber davon würde ich grundsätzlich abraten, weil die Leute dazu neigen, ihre Systeme durcheinander zu bringen, indem sie vergessen, dass sie root...

EINE ANDERE LÖSUNGwäre, den locateBefehl zu verwenden, um alle .txtDateien im gesamten System zu finden. Der locateBefehl durchsucht nicht die Dateihierarchie, sondern verwendet eine Datenbank (die normalerweise täglich aktualisiert wird, also nichtalleDateien können dort sein). Die Datenbank enthält nur Dateien in Verzeichnissen, auf die alle Benutzer zugreifen können. Wenn Sie also die Leseberechtigungen für Ihre eigenen Verzeichnisse entfernt haben, sind Ihre Dateien nicht dort.

Ersetzen wir also den findobigen Befehl durch das locatefast Äquivalent:

$ locate '*.txt' -0 | xargs -0 fgrep texthere

Die -0Option (oder --nullauf einigen Systemen) entspricht der --print0Option von find.

verwandte Informationen