Ich habe einen Ordner mit über 250 Dateien mit jeweils 2 GB. Ich muss in diesen Dateien nach einer Zeichenfolge/einem Muster suchen und das Ergebnis in einer output
ausgeben Datei. 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 zur Beschleunigung des Prozesses verwendet werden kann. Ich weiß nicht, wie ich grep
starten soll im „multi-threaded mode“ und schreibe die Ausgabe in eine einzige output
Datei.
Akzeptierte Antwort:
Dafür gibt es zwei einfache Lösungen. Grundsätzlich mit xargs
oder parallel
.
xargs-Ansatz:
Sie können xargs
verwenden mit find
wie folgt:
find . -type f -print0 | xargs -0 -P number_of_processes grep mypattern > output
Wo Sie number_of_processes
ersetzen werden durch die maximale Anzahl von Prozessen, die Sie starten möchten.
Dies garantiert jedoch keine signifikante Leistung, falls Ihre Leistung durch E/A begrenzt ist. In diesem Fall könnten Sie versuchen, mehr Prozesse zu starten, um die verlorene Zeit beim Warten auf I/Os zu kompensieren.
Außerdem können Sie mit der Einbeziehung von find erweiterte Optionen anstelle von Dateimustern angeben, wie z. B. Änderungszeit usw.
Ein mögliches Problem bei diesem Ansatz, wie in Stéphanes Kommentaren erläutert, wenn es wenige Dateien gibt, xargs
möglicherweise nicht genügend viele Prozesse für sie starten. Eine Lösung wird die Verwendung von -n
sein Option für xargs
um anzugeben, wie viele Argumente gleichzeitig aus der Pipe genommen werden sollen. Einstellung -n1
erzwingt xargs
um für jede einzelne Datei einen neuen Prozess zu starten. Dies kann ein gewünschtes Verhalten sein, wenn die Dateien sehr groß sind (wie im Fall dieser Frage) und es eine relativ kleine Anzahl von Dateien gibt. Wenn die Dateien selbst jedoch klein sind, kann der Aufwand für das Starten eines neuen Prozesses den Vorteil der Parallelität untergraben, in diesem Fall ein größerer -n
Wert wird besser sein. Also das -n
Die Option kann je nach Dateigröße und -anzahl fein abgestimmt werden.
Parallelansatz:
Eine andere Möglichkeit, dies zu tun, 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 über mehrere Hosts verteilt werden (wäre beispielsweise vorteilhaft, wenn Ihr Verzeichnis gemeinsam genutzt wird).
Die einfachste Syntax, die Parallelität verwendet, ist:
find . -type f | parallel -j+1 grep mypattern
wo die Option -j+1
weist parallel an, einen Prozess zu starten, der die Anzahl der Kerne auf Ihrem Computer übersteigt (Dies kann hilfreich sein für Aufgaben mit begrenzter E/A, Sie können sogar versuchen, die Anzahl zu erhöhen).
Parallel hat auch den Vorteil gegenüber xargs
die Reihenfolge der Ausgabe von jedem Prozess tatsächlich beizubehalten und eine zusammenhängende Ausgabe zu erzeugen. Zum Beispiel mit xargs
, wenn Prozess 1 eine Zeile erzeugt, sagen Sie p1L1
, erzeugt Prozess 2 eine Zeile p2L1
, erzeugt Prozess 1 eine weitere Zeile p1L2
, lautet die Ausgabe:
p1L1
p2L1
p1L2
wohingegen mit parallel
die Ausgabe sollte sein:
p1L1
p1L2
p2L1
Dies ist normalerweise nützlicher als xargs
Ausgabe.