grep
ist E / A-gebunden, dh die Geschwindigkeit hängt davon ab, wie schnell die gesuchten Dateien gelesen werden können. Mehrere parallele Suchvorgänge können miteinander um Festplatten-E / A konkurrieren, sodass Sie möglicherweise nicht viel beschleunigen.
Wenn Sie nur übereinstimmende Dateinamen und nicht die tatsächlich gefundenen Übereinstimmungen in den Dateien benötigen, sollten Sie grep mit dem -l
Flag ausführen . Dieses Flag bewirkt, dass grep nur übereinstimmende Dateinamen und nicht die übereinstimmenden Zeilen druckt. Der Wert hier ist, dass es grep erlaubt, die Suche nach einer Datei zu beenden, sobald eine Übereinstimmung gefunden wurde. Dadurch könnte der Arbeitsaufwand für grep reduziert werden.
Wenn Sie nach festen Zeichenfolgen statt nach regulären Ausdrücken suchen, können Sie versuchen, fgrep
statt zu verwenden grep
. Fgrep ist eine Variante von grep, die nach festen Zeichenfolgen sucht. Die Suche nach festen Zeichenfolgen ist schneller als die Suche nach regulären Ausdrücken. Möglicherweise sehen Sie hier keine Verbesserung, da moderne Versionen von grep wahrscheinlich klug genug sind, die Suche nach festen Zeichenfolgen trotzdem zu optimieren.
Wenn Sie mehrere Suchvorgänge parallel ausführen möchten, können Sie dies mit Hilfe von Shell-Dienstprogrammen tun. Eine Möglichkeit wäre, eine Liste von Dateinamen zu erstellen, sie in Teile zu teilen und grep für jede Liste separat auszuführen:
find /path/to/files -type f -print | split -l 10000000 list. for file in list.*; do grep -f $ -l 'some text' > $.out & done wait cat $*.out > filepaths.log rm list.*
Dabei werden find
die Dateien gesucht, die Liste der Dateinamen in zehn Millionen Gruppen aufgeteilt und für jede Gruppe parallel ausgeführt. Die Ausgabe der Greps wird am Ende alle miteinander verbunden. Dies sollte für Dateien mit typischen Namen funktionieren, würde aber für Dateien mit Zeilenumbrüchen beispielsweise fehlschlagen.
Ein anderer Ansatz verwendet xargs. Zuerst müssen Sie ein einfaches Shell-Skript schreiben, das im Hintergrund grep ausführt:
#!/bin/bash grep -l 'search text' "$@" >> grep.$$.out &
Dadurch wird grep in der Liste der Dateien ausgeführt, die als Argumente für das Skript angegeben wurden. Das Ergebnis wird in eine Datei geschrieben, die nach der PID des Prozesses benannt ist. Der grep-Prozess läuft im Hintergrund ab.
Dann würden Sie das Skript so ausführen:
find /path/to/files -type f -print0 | xargs -0 -r /my/grep/script [ wait for those to finish ] cat grep.*.out > filepaths.log rm grep.*.out
In diesem Fall xargs
werden die Dateinamen in Gruppen zusammengefasst und das Skript für jede Gruppe einmal ausgeführt. Das Skript führt für jede Gruppe einmal eine Instanz von grep aus. Sobald alle grep-Instanzen abgeschlossen sind, können Sie deren Ausgaben kombinieren. Leider konnte ich mir keine clevere Möglichkeit vorstellen, automatisch auf die Grep-Instanzen zu warten, um hier fertig zu werden. Daher müssen Sie dies möglicherweise manuell tun.