Primeiro de tudo, não use a lssaída como uma lista de arquivos . Use expansão de shell ou find. Veja abaixo as possíveis consequências do uso indevido de ls + xargs e um exemplo de xargsuso adequado .
1. Maneira simples: para loop
Se você deseja processar apenas os arquivos abaixo A/, um forloop simples deve ser suficiente:
for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done
2. pre1 Por que não ls | xargs ?
Aqui está um exemplo de quão ruim as coisas podem virar se você usar lscom xargspara o trabalho. Considere um cenário a seguir:
primeiro, vamos criar alguns arquivos vazios:
$ touch A/mypreciousfile.dat\ with\ junk\ at\ the\ end.dat
$ touch A/mypreciousfile.dat
$ touch A/mypreciousfile.dat.ans
veja os arquivos e eles não contêm nada:
$ ls -1 A/
mypreciousfile.dat
mypreciousfile.dat with junk at the end.dat
mypreciousfile.dat.ans
$ cat A/*
execute um comando mágico usando xargs:
$ ls A/*.dat | xargs -I file sh -c "echo TRICKED > file.ans"
o resultado:
$ cat A/mypreciousfile.dat
TRICKED with junk at the end.dat.ans
$ cat A/mypreciousfile.dat.ans
TRICKED
Então, você acabou de substituir ambos mypreciousfile.date mypreciousfile.dat.ans. Se houvesse algum conteúdo nesses arquivos, ele teria sido apagado.
2. Usando xargs : da maneira correta com find
Se você quiser insistir em usar xargs, use -0(nomes terminados em nulo):
find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'
Observe duas coisas:
- Dessa forma, você criará arquivos com
.dat.ansfinal;
- isso será interrompido se algum nome de arquivo contiver um sinal de aspas (
").
Ambos os problemas podem ser resolvidos por diferentes formas de invocação de shell:
find A/ -name "*.dat" -type f -print0 | xargs -0 -L 1 bash -c './a.out < "$0" > "${0%dat}ans"'
3. Tudo feito dentro find ... -exec
find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;
Isso, novamente, produz .dat.ansarquivos e será interrompido se os nomes dos arquivos contiverem ". Para fazer isso, use bashe altere a maneira como é chamado:
find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;