Zunächst einmal nicht verwendet ls
Ausgabe als Dateiliste . Verwenden Sie die Shell-Erweiterung oder find
. Nachfolgend finden Sie mögliche Folgen des Missbrauchs von ls + xargs und ein Beispiel für die ordnungsgemäße xargs
Verwendung.
1. Einfacher Weg: for loop
Wenn Sie nur die Dateien unter verarbeiten möchten, sollte A/
eine einfache for
Schleife ausreichen:
for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done
2. pre1 Warum nicht ls | xargs
?
Hier ist ein Beispiel dafür , wie schlecht die Dinge, wenn Sie verwenden ls
mit xargs
für den Job. Stellen Sie sich folgendes Szenario vor:
Lassen Sie uns zuerst einige leere Dateien erstellen:
$ touch A/mypreciousfile.dat\ with\ junk\ at\ the\ end.dat
$ touch A/mypreciousfile.dat
$ touch A/mypreciousfile.dat.ans
siehe die Dateien und dass sie nichts enthalten:
$ ls -1 A/
mypreciousfile.dat
mypreciousfile.dat with junk at the end.dat
mypreciousfile.dat.ans
$ cat A/*
Führe einen magischen Befehl aus mit xargs
:
$ ls A/*.dat | xargs -I file sh -c "echo TRICKED > file.ans"
das Ergebnis:
$ cat A/mypreciousfile.dat
TRICKED with junk at the end.dat.ans
$ cat A/mypreciousfile.dat.ans
TRICKED
Sie haben es also gerade geschafft, beide mypreciousfile.dat
und zu überschreiben mypreciousfile.dat.ans
. Wenn sich Inhalte in diesen Dateien befunden hätten, wären sie gelöscht worden.
2. Verwenden xargs
: den richtigen Weg mit find
Wenn Sie darauf bestehen möchten xargs
, verwenden Sie -0
(nullterminierte Namen):
find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'
Beachten Sie zwei Dinge:
- Auf diese Weise erstellen Sie Dateien mit
.dat.ans
Endung.
- Dies wird unterbrochen, wenn ein Dateiname ein Anführungszeichen (
"
) enthält.
Beide Probleme können auf unterschiedliche Weise durch Aufrufen der Shell gelöst werden:
find A/ -name "*.dat" -type f -print0 | xargs -0 -L 1 bash -c './a.out < "$0" > "${0%dat}ans"'
3. Alles innerhalb erledigt find ... -exec
find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;
Dies erzeugt wiederum .dat.ans
Dateien und bricht ab, wenn Dateinamen enthalten "
. Verwenden bash
und ändern Sie dazu die Art und Weise, wie es aufgerufen wird:
find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;