Aufgaben in der BASH parallelisieren


Heute wollte ich in der Bash (genauer: in der Bash meiner Cygwin-Installation) mehrere große Logfiles durchsuchen. Mit grep habe ich nach einer bestimmten Zeichenfolge ausschau gehalten und die Ausgabe sollte pro Datei in einer eigenen Ausgabedatei landen.

Mein erster Ansatz war eine Schleife über die Verzeichnisse mit den Logfiles:

for i in *;do grep -hE "^[0-9\.]+" $i/access_log* > $i-ips.txt;done

Dabei stellte sich schnell heraus, dass die Logfiles mit mehreren Hundert Megabytes etwas zu groß für so eine Herangehensweise waren. Dann ist mir eingefallen, dass ich auf meinem fetten Intel Core i7 870 mit 8 Kernen sitze. Also lässt sich so eine Aufgabe prima in einzelne Prozesse aufsplitten, damit die CPU auch mal ein wenig ausgelastet wird.

Hier ist mein zweiter Ansatz für die Schleife über alle Verzeichnisse mit Logfiles:

for i in *;do (grep -hE "^[0-9\.]+" $i/access_log* > $i-ips.txt &);done

Zur Erläuterung: Die Schleife läuft über alle Dateien im aktuellen Verzeichnis (ok, da liegen bei mir nur Verzeichnisse…) und führt anschliessend ein grep auf allen access_log innerhalb der gefundenen Verzeichnisse. Dieses grep wird in einem neuen Prozess gestartet und schreibt die Ausgabe in eine Datei mit dem Verzeichnisnamen als Prefix.

Und schon laufen meine Prozessorkerne auf 80% und schreiben mehrere Hundert Megabyte in 6 unterschiedliche Ausgabedateien. ;-)

Update

Wenn ihr damit noch nicht zufrieden seid, könnt ihr auch diese Variante mit xargs ausprobieren:

ls -1| xargs --max-procs=6 -n 1 grep -RhE "^[0-9\.]+" >>ips.txt

Weitere Artikel

Crossfit Open WOD 17.5

Crossfit Open WOD 17.4

Crossfit Open WOD 17.3

Crossfit Open Workout 17.2

Crossfit Open Workout 17.1

Run Feedbin in your local Kubernetes cluster

Running Threema Web in Docker

Neues Workout Video

Diät Update #1

Workout 21.01.2017