まず、出力をファイルリストとして使用しないls
でください。シェル拡張またはを使用しますfind
。ls + xargsの誤用の潜在的な結果と適切なxargs
使用例については、以下を参照してください。
1.簡単な方法:forループ
のファイルのみを処理する場合A/
は、単純なfor
ループで十分です。
for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done
2. pre1なぜ ls | xargs
ですか?
仕事でを使用するls
とxargs
、悪いことがどのように変わるかの例を次に示します。次のシナリオを検討してください。
最初に、いくつかの空のファイルを作成しましょう。
$ touch A/mypreciousfile.dat\ with\ junk\ at\ the\ end.dat
$ touch A/mypreciousfile.dat
$ touch A/mypreciousfile.dat.ans
ファイルを参照し、何も含まれていないことを確認してください。
$ ls -1 A/
mypreciousfile.dat
mypreciousfile.dat with junk at the end.dat
mypreciousfile.dat.ans
$ cat A/*
を使用してマジックコマンドを実行しxargs
ます。
$ ls A/*.dat | xargs -I file sh -c "echo TRICKED > file.ans"
結果:
$ cat A/mypreciousfile.dat
TRICKED with junk at the end.dat.ans
$ cat A/mypreciousfile.dat.ans
TRICKED
したがって、mypreciousfile.dat
との両方を上書きすることができましたmypreciousfile.dat.ans
。それらのファイルにコンテンツがあった場合、それは消去されていたでしょう。
2.使用 xargs
:での適切な方法 find
の使用を主張したい場合はxargs
、-0
(ヌル終了名)を使用します。
find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'
2つのことに注意してください。
- このようにして、ファイル名の
.dat.ans
末尾を作成します。
- 一部のファイル名に引用符()が含まれている場合、これは壊れます
"
。
両方の問題は、異なる方法でシェルを呼び出すことで解決できます。
find A/ -name "*.dat" -type f -print0 | xargs -0 -L 1 bash -c './a.out < "$0" > "${0%dat}ans"'
3.内で行われるすべて find ... -exec
find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;
これもまた、.dat.ans
ファイルを生成し、ファイル名にが含まれて"
いると壊れます。それを実行するにbash
は、呼び出し方法を使用して変更します。
find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;