Zunächst einmal nicht verwendet lsAusgabe 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 xargsVerwendung.
1. Einfacher Weg: for loop
Wenn Sie nur die Dateien unter verarbeiten möchten, sollte A/eine einfache forSchleife 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 lsmit xargsfü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.datund 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.ansEndung.
- 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.ansDateien und bricht ab, wenn Dateinamen enthalten ". Verwenden bashund ä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"' {} \;