Ich habe einen Ordner mit mehr als 250 Dateien mit jeweils 2 GB. Ich muss in diesen Dateien nach einer Zeichenfolge / einem Muster suchen und das Ergebnis in einer output
Datei ausgeben . Ich weiß, dass ich den folgenden Befehl ausführen kann, aber er ist zu langsam !!
grep mypattern * > output
Ich möchte es beschleunigen. Als Programmierer in Java weiß ich, dass Multithreading verwendet werden kann, um den Prozess zu beschleunigen. Ich bin nicht sicher, wie ich grep
im "Multithread-Modus" starten und die Ausgabe in eine einzelne output
Datei schreiben soll .
grep
parallelism
Abhishek
quelle
quelle
Antworten:
Hierfür gibt es zwei einfache Lösungen. Grundsätzlich mit
xargs
oderparallel
.xargs Ansatz:
Sie können
xargs
mitfind
wie folgt verwenden:Wobei Sie
number_of_processes
durch die maximale Anzahl von Prozessen ersetzen, die Sie starten möchten. Es wird jedoch nicht garantiert, dass Sie eine signifikante Leistung erhalten, wenn Ihre Leistung auf E / A beschränkt ist. In diesem Fall können Sie versuchen, weitere Prozesse zu starten, um die Wartezeit auf E / A-Vorgänge zu kompensieren.Außerdem können Sie mit find erweiterte Optionen angeben, anstatt nur Dateimuster wie Änderungszeit usw. anzugeben.
Ein mögliches Problem bei diesem Ansatz ist, wie in den Kommentaren von Stéphane erläutert, dass wenn nur wenige Dateien vorhanden sind,
xargs
möglicherweise nicht genügend viele Prozesse für diese gestartet werden. Eine Lösung besteht darin, mit der-n
Option fürxargs
anzugeben, wie viele Argumente gleichzeitig aus der Pipe entnommen werden sollen. Die Einstellung-n1
erzwingtxargs
, dass für jede einzelne Datei ein neuer Prozess gestartet wird. Dies kann ein gewünschtes Verhalten sein, wenn die Dateien sehr groß sind (wie im Fall dieser Frage) und eine relativ kleine Anzahl von Dateien vorhanden ist. Wenn die Dateien selbst klein sind, kann der Mehraufwand beim Starten eines neuen Prozesses den Vorteil der Parallelität beeinträchtigen. In diesem Fall ist ein höherer-n
Wert besser. Daher kann die-n
Option je nach Dateigröße und Anzahl fein eingestellt werden.Parallele Annäherung:
Eine andere Möglichkeit ist die Verwendung des Ole Tange GNU Parallel-Tools
parallel
( hier verfügbar ). Dies bietet eine genauere Kontrolle über die Parallelität und kann sogar auf mehrere Hosts verteilt werden (wäre von Vorteil, wenn Ihr Verzeichnis beispielsweise gemeinsam genutzt wird). Die einfachste parallele Syntax ist:find . -type f | parallel -j+1 grep mypattern
Wobei die Option
-j+1
parallel anweist, einen Prozess zu starten, der die Anzahl der Kerne auf Ihrem Computer überschreitet (Dies kann hilfreich sein, wenn die Anzahl der E / A-Aufgaben begrenzt ist. Möglicherweise versuchen Sie sogar, die Anzahl zu erhöhen).Parallel hat auch den Vorteil, dass
xargs
die Reihenfolge der Ausgabe von jedem Prozess beibehalten und eine zusammenhängende Ausgabe generiert wird. Beispiel:xargs
Wenn Prozess 1 eine Zeile generiert, z. B.p1L1
Prozess 2 eine Zeile generiertp2L1
, Prozess 1 eine weitere Zeile generiert, lautetp1L2
die Ausgabe:während mit
parallel
der Ausgabe sollte sein:Dies ist normalerweise nützlicher als die
xargs
Ausgabe.quelle
-n
in Kombination mit-P
. Andernfalls könnenxargs
möglicherweise nicht mehrere Prozesse gestartet werden, wenn zwei wenige Dateien vorhanden sind.grep
pro Datei starten . Wenn die Dateien nicht sehr groß sind und es nur sehr wenige gibt, sollten Sie sie wahrscheinlich etwas vergrößern, da Sie Ihre Zeit damit verbringen, grep-Prozesse zu starten und anzuhalten, anstatt in Dateien zu suchen.Es gibt mindestens zwei Möglichkeiten, die Geschwindigkeit der CPU zu erhöhen:
Wenn Sie nach einer festen Zeichenfolge und nicht nach einem regulären Ausdruck suchen, geben Sie das
-F
Flag an.Wenn Ihr Muster nur ASCII ist, verwenden Sie ein 8-Bit-Gebietsschema anstelle von UTF-8, z
LC_ALL=C grep ...
.Dies hilft jedoch nicht, wenn Ihre Festplatte der Engpass ist. In diesem Fall hilft wahrscheinlich auch das Parallelisieren nicht.
quelle
man grep
"Direkter Aufruf als entweder egrep oder fgrep ist veraltet, wird aber bereitgestellt, damit historische Anwendungen, die darauf angewiesen sind, unverändert ausgeführt werden können." Ichgrep -F
Wenn das Problem nicht E / A-gebunden ist, können Sie ein Tool verwenden, das für die Mehrkernverarbeitung optimiert ist.
Vielleicht möchten Sie einen Blick auf sift ( http://sift-tool.org , Haftungsausschluss: Ich bin der Autor dieses Tools) oder den Silver Searcher ( https://github.com/ggreer/the_silver_searcher ) werfen .
Der Silver Searcher hat eine Dateigrößenbeschränkung von 2 GB, wenn Sie ein reguläres Muster und keine einfache Zeichenfolgensuche verwenden.
quelle