Ich habe einen Ordner mit vielen Dateien (xyz1, xyz2, bis zu xyz5025) und muss auf jedem ein Skript ausführen, um xyz1.faa, xyz2.faa usw. als Ausgabe zu erhalten.
Der Befehl für eine einzelne Datei lautet:
./transeq xyz1 xyz1.faa -table 11
Gibt es eine Möglichkeit, das automatisch zu tun? Vielleicht eine For-Do-Combo?
for file in xyz*; do ./transeq "$file" "${file}.faa" -table 11; done
. Ich schreibe die ganze Zeit so etwas. Und wenn Sie überprüfen möchten, ob die Dateinamen usw. wie gewünscht erweitert werden, setzen Sieecho
nachdo
dem ersten Mal ein Rechtszeichen und gehen Sie dann zurück in Ihren Shell-Verlauf und löschen Sie ihn beim zweiten Mal."$file".faa
ist als Teil eines interaktiven Einzeilers etwas einfacher einzugeben und sicher, da.faa
es keine Shell-Metazeichen enthält, die in Anführungszeichen gesetzt werden müssen.xyz*
Teillauf durchführen und die Schleife neu starten möchten, nimmt der Glob auch .faa-Dateien auf. Führen Sie für bashshopt -s extglob
( reference ) aus undfor file in xyz!(*.faa) ...
schließen Sie dann die .faa-Dateien vom Senden durch die Schleife aus.Wenn Sie GNU Parallel installieren , können Sie dies wie folgt parallel tun:
Wenn Ihr Programm CPU-intensiv ist, sollte es ziemlich schnell laufen.
quelle
Sie können so etwas in einer
bash
Befehlszeile ausführen:Wir generieren die Ganzzahlen von 1 bis 5025, one / line,
{}
und geben sie dann einzeln an xargs weiter, wobei die Ganzzahl in ./transeq eingekapselt und dann in geeigneter Weise in die Befehlszeile transplantiert wird.Wenn Sie nicht über die Möglichkeit zur Klammererweiterung verfügen, können
{n..m}
Sie dasseq
Dienstprogramm aufrufen , um diese Zahlen zu generieren.Oder Sie können die numerische Generierung immer emulieren über:
quelle
for i in {1..5025}; do ./transeq "xyz$i" "xyz$i".faa -table 11; done
ist viel einfacher zu denken und zu tippen. Wenn Sie möchten, dass Befehle vor dem Ausführen gedruckt werden, verwenden Sieset -x
.for i in
{1..5025}
erzielen Sie genau das gleiche Ergebnis wie bei Ihnen. Sie könnten auchfor ((i=1 ; i<=5025 ; i++)); do ./transeq "xyz$i" "xyz$i".faa -table 11; done
in Bash schreiben , aber ich verwende normalerweise die{a..b}
Range-Syntax, weil es schneller zu tippen ist.Die Verwendung von find ist nützlich, wenn sich Ihre Dateien in Verzeichnissen befinden
quelle
Angenommen, Sie haben mehr als einen Kern und jeder Aufruf kann unabhängig von den anderen ausgeführt werden, werden Sie mit parallelen Läufen eine ziemliche Beschleunigung erzielen.
Ein relativ einfacher Weg, dies zu tun, ist über den
-P
Parameter vonxargs
- zum Beispiel, wenn Sie 4 Kerne haben:Das
-n 1
befiehltxargs
, für jeden Aufruf nur ein Argument aus der Liste auszuwählen (standardmäßig würde es viel passieren) , und das-P 4
befiehlt, 4 Prozesse gleichzeitig zu erzeugen - wenn einer stirbt, wird ein neuer erzeugt.IMHO, Sie müssen GNU für diesen einfachen Fall nicht parallel installieren -
xargs
reicht aus.quelle
Sie können verwenden
xarg
ls | xargs -L 1 -d '\n' your-desired-command
-L 1
Bewirkt, dass jeweils 1 Element übergeben wird-d '\n'
make output ofls
wird basierend auf der neuen Zeile aufgeteilt.quelle