Ich habe ein Shell-Scripting-Problem, bei dem ich ein Verzeichnis voller Eingabedateien (jede Datei enthält viele Eingabezeilen) bekomme, und ich muss sie einzeln verarbeiten und jede ihrer Ausgaben in eine eindeutige Datei umleiten (auch bekannt als file_1.input-Anforderungen) in file_1.output zu erfassen, und so weiter).
Vor der Parallelisierung durchlieferte ich einfach jede Datei im Verzeichnis und führte meinen Befehl aus, während ich eine Art Timer- / Zähltechnik ausführte, um die Prozessoren nicht zu überfordern (vorausgesetzt, jeder Prozess hatte eine konstante Laufzeit). Ich weiß jedoch, dass dies nicht immer der Fall sein wird. Daher scheint die Verwendung einer "parallelen" Lösung der beste Weg zu sein, um das Multithreading von Shell-Skripten zu erreichen, ohne benutzerdefinierten Code zu schreiben.
Obwohl ich mir überlegt habe, wie ich jede dieser Dateien parallel verarbeiten kann (und meine Kerne effizient verwalten kann), scheinen sie alle hacky zu sein. Ich halte das für einen ziemlich einfachen Anwendungsfall und würde es daher vorziehen, es so sauber wie möglich zu halten (und nichts in den parallelen Beispielen scheint als mein Problem herauszuspringen.
Jede Hilfe wäre dankbar!
Beispiel für ein Eingabeverzeichnis:
> ls -l input_files/
total 13355
location1.txt
location2.txt
location3.txt
location4.txt
location5.txt
Skript:
> cat proces_script.sh
#!/bin/sh
customScript -c 33 -I -file [inputFile] -a -v 55 > [outputFile]
Update : Nachdem ich Ole's Antwort unten gelesen hatte, konnte ich die fehlenden Teile für meine eigene parallele Implementierung zusammenstellen. Während seine Antwort großartig ist, sind hier meine zusätzlichen Nachforschungen und Notizen, die ich gemacht habe:
Anstatt meinen gesamten Prozess auszuführen, begann ich mit einem Proof-of-Concept-Befehl, um seine Lösung in meiner Umgebung zu beweisen. Siehe meine zwei verschiedenen Implementierungen (und Hinweise):
find /home/me/input_files -type f -name *.txt | parallel cat /home/me/input_files/{} '>' /home/me/output_files/{.}.out
Verwendet find (nicht ls, das kann Probleme verursachen), um alle zutreffenden Dateien in meinem Eingabedateiverzeichnis zu finden und leitet ihren Inhalt dann in ein separates Verzeichnis und eine separate Datei um. Mein Problem von oben war das Lesen und Umleiten (das eigentliche Skript war einfach), daher war das Ersetzen des Skripts durch cat ein guter Proof of Concept.
parallel cat '>' /home/me/output_files/{.}.out ::: /home/me/input_files/*
Diese zweite Lösung verwendet das Eingabevariablen-Paradigma von parallel, um die Dateien einzulesen. Für Anfänger war dies jedoch viel verwirrender. Mit find a and pipe habe ich meine Bedürfnisse bestens erfüllt.