2013-10-30 1 views
10

Diese Frage zu How to use grep efficiently?Wie grep mit großen (in Millionen) Anzahl von Dateien verwenden, um Zeichenfolge zu suchen und in wenigen Minuten

Ich versuche, für einen „string“ in einem Ordner zu suchen, verwandt Ergebnis erhält die hat 8-10 Millionen kleine (~ 2-3kb) reine Textdateien. Ich muss alle Dateien wissen, die "Zeichenfolge" haben.

Zuerst habe ich diese

grep "string" 

Das super langsam war.

Dann habe ich versucht

grep * "string" {} \; -print 

Basierend auf verknüpfte Frage, habe ich diese

find . | xargs -0 -n1 -P8 grep -H "string" 

ich diesen Fehler:

xargs: argument line too long 

Kennt jemand eine Möglichkeit, diese Aufgabe zu erfüllen relativ schneller?

Ich führe diese Suche auf einem Server mit mehr als 50 GB verfügbaren Arbeitsspeicher und 14 Kerne CPU. Ich wünschte, irgendwie könnte ich all diese Verarbeitungsleistung nutzen, um diese Suche schneller auszuführen.

+0

Möchten Sie wissen, in welcher Datei die Zeichenfolge ist? Oder genügt es zu wissen, dass sich die Zeichenfolge in einer oder mehreren Dateien im Verzeichnis befindet? –

+0

Ich muss den ganzen Dateinamen wissen, wo die Zeichenfolge gefunden wird. – Watt

Antwort

9

Sie sollten stattdessen -0 Argument xargs und bis -n Parameter entfernen:

... | xargs -n16 ... 
+0

+1 Danke! es funktionierte. Ich werde auf einige weitere Antworten warten, bevor ich dies als Antwort akzeptiere. – Watt

+0

'-n64' oder' -n128' könnte eine realistischere Zahl sein. – phs

+0

ist 'n' die Anzahl der gleichzeitig verwendeten Prozesse? – Watt

0

8 Millionen Dateien sind eine Menge in einem Verzeichnis! 8 Millionen mal 2kb sind 16GB und Sie haben 50GB RAM. Ich denke an eine RAM-Disk ...

+0

Ja, es sind zu viele Dateien in einem Ordner. Kannst du bitte deine Lösung so ausarbeiten, wie die "Schnur" schneller suchen? – Watt

+0

Leider habe ich noch keine Lösung ... Ich versuche immer noch die Parameter der Frage zu verstehen. Welches Betriebssystem verwenden Sie? Welches Dateisystem verwendest du? Haben Sie versucht, den "find" -Befehl eigenständig auszuführen und zu timpfen? Zeit finden. | wc -l –

+0

Betriebssystem: Ubuntu (neueste Version). Finden Sie das Ergebnis innerhalb von 2 Sekunden – Watt

10

Es ist nicht so großen Stapel von Dateien (ein dickes Lob an 10⁷ Dateien - ein Messys Traum) aber ich erstellt 100k-Dateien (400 MB insgesamt) mit

for i in {1..100000}; do head -c 10 /dev/urandom > dummy_$i; done 

und machte einige Tests für die reine Neugier (das Schlüsselwort ich war auf der Suche ausgewählt wird zufällig):

> time find . | xargs -n1 -P8 grep -H "10" 
real 0m22.626s 
user 0m0.572s 
sys 0m5.800s 

> time find . | xargs -n8 -P8 grep -H "10" 
real 0m3.195s 
user 0m0.180s 
sys 0m0.748s 

> time grep "10" * 
real 0m0.879s 
user 0m0.512s 
sys 0m0.328s 

> time awk '/10/' * 
real 0m1.123s 
user 0m0.760s 
sys 0m0.348s 

> time sed -n '/10/p' * 
real 0m1.531s 
user 0m0.896s 
sys 0m0.616s 

> time perl -ne 'print if /10/' * 
real 0m1.428s 
user 0m1.004s 
sys 0m0.408s 

Btw. Es gibt keinen großen Unterschied in der Laufzeit, wenn ich die Ausgabe mit Rohrleitungen STDOUT zu /dev/null unterdrücke. Ich benutze Ubuntu 12.04 auf einem nicht so leistungsfähigen Laptop;) Meine CPU ist Intel (R) Core (TM) i3-3110M CPU @ 2.40GHz.

Mehr Neugier:

> time find . | xargs -n1 -P8 grep -H "10" 1>/dev/null 

real 0m22.590s 
user 0m0.616s 
sys 0m5.876s 

> time find . | xargs -n4 -P8 grep -H "10" 1>/dev/null 

real m5.604s 
user 0m0.196s 
sys 0m1.488s 

> time find . | xargs -n8 -P8 grep -H "10" 1>/dev/null 

real 0m2.939s 
user 0m0.140s 
sys 0m0.784s 

> time find . | xargs -n16 -P8 grep -H "10" 1>/dev/null 

real 0m1.574s 
user 0m0.108s 
sys 0m0.428s 

> time find . | xargs -n32 -P8 grep -H "10" 1>/dev/null 

real 0m0.907s 
user 0m0.084s 
sys 0m0.264s 

> time find . | xargs -n1024 -P8 grep -H "10" 1>/dev/null 

real 0m0.245s 
user 0m0.136s 
sys 0m0.404s 

> time find . | xargs -n100000 -P8 grep -H "10" 1>/dev/null 

real 0m0.224s 
user 0m0.100s 
sys 0m0.520s 
+1

+1 Für Benchmarking und wichtige Informationen – Watt

-2

Wenn du hast so viel RAM, warum es nicht lesen alle in den Speicher und verwenden eine Bibliothek für reguläre Ausdrücke zu suchen? Es ist ein einfaches C-Programm:

#include <fcntl.h> 
    #include <regex.h> 
    ... 
Verwandte Themen