GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Rekursives Grep Vs Find / -type F -exec Grep {}; Was ist effizienter/schneller?

Was ist effizienter, um herauszufinden, welche Dateien in einem gesamten Dateisystem eine Zeichenfolge enthalten:rekursives grep oder suchen mit grep in einer exec-Anweisung? Ich nehme an, find wäre effizienter, weil Sie zumindest etwas filtern können, wenn Sie die Dateierweiterung oder eine Regex kennen, die zum Dateinamen passt, aber wenn Sie nur -type f kennen Welches ist besser? GNU grep 2.6.3; find (GNU findutils) 4.4.2

Beispiel:

grep -r -i 'the brown dog' /

find / -type f -exec grep -i 'the brown dog' {} ;

Akzeptierte Antwort:

Ich bin mir nicht sicher:

grep -r -i 'the brown dog' /*

ist wirklich das, was du gemeint hast. Das würde grep rekursiv in allen nicht versteckten Dateien und Verzeichnissen in / bedeuten (aber schauen Sie trotzdem in versteckte Dateien und Verzeichnisse darin).

Angenommen, Sie meinten:

grep -r -i 'the brown dog' /

Ein paar Dinge zu beachten:

  • Nicht alle grep Implementierungen unterstützen -r . Und bei denen, die dies tun, unterscheidet sich das Verhalten:Einige folgen symbolischen Links zu Verzeichnissen, wenn sie den Verzeichnisbaum durchlaufen (was bedeutet, dass Sie möglicherweise mehrmals in derselben Datei suchen oder sogar in Endlosschleifen laufen), andere nicht. Einige werden in Gerätedateien nachsehen (und es wird einige Zeit in /dev/zero dauern zum Beispiel) oder Pipes oder Binärdateien…, manche nicht.
  • Effizient wie grep beginnt, in Dateien zu suchen, sobald es sie entdeckt. Aber während es in einer Datei sucht, sucht es nicht mehr nach weiteren Dateien, in denen es suchen kann (was in den meisten Fällen wahrscheinlich genauso gut ist)

Ihr:

find / -type f -exec grep -i 'the brown dog' {} ;

(-r entfernt was hier keinen Sinn machte) ist schrecklich ineffizient, weil Sie ein grep ausführen pro Datei. ; sollte nur für Befehle verwendet werden, die nur ein Argument akzeptieren. Außerdem hier, weil grep sucht nur in einer Datei, der Dateiname wird nicht gedruckt, sodass Sie nicht wissen, wo die Übereinstimmungen sind.

Sie schauen nicht in Gerätedateien, Pipes, Symlinks …, Sie folgen keinen Symlinks, aber Sie schauen möglicherweise immer noch in Dinge wie /proc/mem .

find / -type f -exec grep -i 'the brown dog' {} +

wäre viel besser, weil so wenig grep Befehle wie möglich ausgeführt werden. Sie erhalten den Dateinamen, es sei denn, der letzte Lauf hat nur eine Datei. Verwenden Sie dafür besser:

find / -type f -exec grep -i 'the brown dog' /dev/null {} +

oder mit GNU grep :

find / -type f -exec grep -Hi 'the brown dog' {} +

Beachten Sie, dass grep wird erst mit find gestartet hat genug Dateien gefunden, um darauf herumzukauen, also wird es eine anfängliche Verzögerung geben. Und find wird bis zum vorherigen grep nicht weiter nach weiteren Dateien suchen ist zurückgekommen. Das Zuweisen und Weitergeben der großen Dateiliste hat einige (wahrscheinlich vernachlässigbare) Auswirkungen, also wird es insgesamt wahrscheinlich weniger effizient sein als ein grep -r die keinem Symlink folgt oder in Geräte hineinschaut.

Verwandte Themen:Wie funktionieren ${0##*/} und ${0%/*}?

Mit GNU-Tools:

find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'

Wie oben, so wenig grep Instanzen wie möglich werden ausgeführt, aber find wird weiter nach weiteren Dateien suchen, während das erste grep Der Aufruf sucht im ersten Batch. Das kann ein Vorteil sein oder auch nicht. Beispiel:Bei Daten, die auf Rotationsfestplatten gespeichert sind, find und grep Der Zugriff auf Daten, die an verschiedenen Orten auf der Festplatte gespeichert sind, verlangsamt den Festplattendurchsatz, da sich der Festplattenkopf ständig bewegt. In einem RAID-Setup (wo find und grep kann auf verschiedene Festplatten zugreifen) oder auf SSDs, das könnte einen positiven Unterschied machen.

In einem RAID-Setup mehrere gleichzeitig ausführen grep Anrufungen könnten auch die Dinge verbessern. Immer noch mit GNU-Tools auf RAID1-Speicher mit 3 Festplatten,

find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'

kann die Leistung erheblich steigern. Beachten Sie jedoch, dass das zweite grep wird erst gestartet, wenn genügend Dateien gefunden wurden, um das erste grep zu füllen Befehl. Sie können ein -n hinzufügen Option zu xargs damit dies früher geschieht (und weniger Dateien pro grep übergeben werden Aufruf).

Beachten Sie auch, dass Sie beim Umleiten von xargs Ausgabe an etwas anderes als ein Endgerät, dann greps s beginnen, ihre Ausgabe zu puffern, was bedeutet, dass die Ausgabe dieser grep s werden wahrscheinlich falsch interleaved. Sie müssten stdbuf -oL verwenden (wo verfügbar wie unter GNU oder FreeBSD) auf ihnen, um dies zu umgehen (Sie haben möglicherweise immer noch Probleme mit sehr langen Zeilen (normalerweise>4KiB)) oder lassen Sie jede ihre Ausgabe in eine separate Datei schreiben und am Ende alle verketten.

Hier ist die gesuchte Zeichenfolge festgelegt (kein regulärer Ausdruck), also verwenden Sie -F Option einen Unterschied machen könnte (unwahrscheinlich, da grep Implementierungen wissen das bereits zu optimieren).

Eine andere Sache, die einen großen Unterschied machen könnte, ist das Festlegen des Gebietsschemas auf C, wenn Sie sich in einem Multi-Byte-Gebietsschema befinden:

find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'

Um zu vermeiden, in /proc zu schauen , /sys …, verwenden Sie -xdev und geben Sie die Dateisysteme an, in denen Sie suchen möchten:

LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +

Oder löschen Sie die Pfade, die Sie ausdrücklich ausschließen möchten:

LC_ALL=C find / ( -path /dev -o -path /proc -o -path /sys ) -prune -o 
  -type f -exec grep -i 'the brown dog' /dev/null {} +

Linux
  1. Suchen -exec + Vs Finden | Xargs:Welche soll man wählen?

  2. Drucken von Dateinamen zusammen mit Grep-Ergebnissen in Find -exec?

  3. Brechen Sie von Find ab, wenn ein -exec fehlschlägt?

  4. Wie finde ich mehrere Zeichenfolgen in Dateien?

  5. find -exec cmd {} + vs | xargs

Grep-Befehl in Linux (Text in Dateien suchen)

So finden Sie eine Zeichenfolge in einer Datei unter Linux

Finden Sie Text in Dateien unter Linux mit grep

rekursives grep:Bestimmte Verzeichnisse ausschließen

Was ist effizienter - tar- oder zip-Komprimierung? Was ist der Unterschied zwischen tar und zip?

Wie grep Zeilen, die mehr als eine bestimmte Anzahl von Sonderzeichen enthalten