Prima di tutto, non utilizzare l' ls
output come elenco di file . Utilizzare l'espansione della shell o find
. Vedi sotto per le potenziali conseguenze dell'uso improprio di ls + xargs e un esempio di xargs
uso corretto .
1. Modo semplice: per loop
Se vuoi elaborare solo i file sotto A/
, un semplice for
ciclo dovrebbe essere sufficiente:
for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done
2. pre1 Perché no ls | xargs
?
Ecco un esempio di come le cose difettose possono girare se si utilizza ls
con xargs
per il lavoro. Considera uno scenario seguente:
prima creiamo alcuni file vuoti:
$ touch A/mypreciousfile.dat\ with\ junk\ at\ the\ end.dat
$ touch A/mypreciousfile.dat
$ touch A/mypreciousfile.dat.ans
vedere i file e che non contengono nulla:
$ ls -1 A/
mypreciousfile.dat
mypreciousfile.dat with junk at the end.dat
mypreciousfile.dat.ans
$ cat A/*
esegui un comando magico usando xargs
:
$ ls A/*.dat | xargs -I file sh -c "echo TRICKED > file.ans"
il risultato:
$ cat A/mypreciousfile.dat
TRICKED with junk at the end.dat.ans
$ cat A/mypreciousfile.dat.ans
TRICKED
Quindi sei appena riuscito a sovrascrivere sia mypreciousfile.dat
e mypreciousfile.dat.ans
. Se ci fosse del contenuto in quei file, sarebbe stato cancellato.
2. Utilizzo xargs
: nel modo corretto con find
Se desideri insistere sull'uso xargs
, usa -0
(nomi con terminazione null):
find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'
Nota due cose:
- in questo modo creerai file con
.dat.ans
finale;
- questo si interromperà se il nome di un file contiene un segno di virgolette (
"
).
Entrambi i problemi possono essere risolti con diversi modi di invocazione della shell:
find A/ -name "*.dat" -type f -print0 | xargs -0 -L 1 bash -c './a.out < "$0" > "${0%dat}ans"'
3. Tutto fatto all'interno find ... -exec
find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;
Questo, di nuovo, produce .dat.ans
file e si romperà se i nomi dei file contengono "
. Per fare ciò, usa bash
e cambia il modo in cui viene invocato:
find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;