xargs と stdin/stdout リダイレクト

xargs と stdin/stdout リダイレクト

私は走りたいです:

./a.out < x.dat > x.ans

それぞれ*.datディレクトリ内のファイル

もちろん、これはbash / python /すべてのスクリプトを介して行うことができますが、私はセクシーな風刺を書くのが好きです。私が達成できるのは(まだstdoutなし)です。

ls A/*.dat | xargs -I file -a file ./a.out

しかし、-ㅏ置換-str 'ファイル'はxargsでは認識されません。

助けてくれてありがとう。

答え1

まず、ls出力をファイルのリストとして使用しないでください。シェル拡張を使用するか、find潜在的な結果については以下を参照してください。ls+xargs誤用と正しい使用の例xargs

1. 簡単な方法:~のためリング

以下のファイルのみを処理するには、A/単純なforループで十分です。

for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done

2.なぜ   pre1でls | xargsはないのですか?

ls以下は、withを使用して操作を実行すると、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 

引き続き使用するには(nullで終わる名前)をxargs使用してください。-0

find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'

2つの点に注意してください。

  1. これにより、.dat.ans次に終わるファイルを作成できます。
  2. これ壊れるファイル名に引用符(")が含まれている場合。

2つの問題は、異なるシェル呼び出し方法によって解決できます。

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"' {} \;

答え2

GNU並列処理を使用する:

parallel ./a.out "<{} >{.}.ans" ::: A/*.dat

ボーナス:処理を並列に実行できます。

詳しくは、紹介ビデオをご覧ください。http://www.youtube.com/watch?v=OpaiGYxkSuQ

答え3

次のようにしてみてください(構文は使用するシェルによって異なる場合があります)。

$ for i in $(find A/ -name \*.dat); do ./a.out < ${i} > ${i%.dat}.ans; done

答え4

少なくともxargsでシェル呼び出しが必要だと思います。

ls A/*.dat | xargs -I file sh -c "./a.out < file > file.ans"

編集:ファイル名にスペースが含まれている場合、この方法は機能しないことに注意してください。仕事できません。 xargs が空白を正しく理解するために find -0 と xargs -0 を使用しても、-c シェル呼び出しのためにガタガタになります。しかし、OPはxargsソリューションを明示的に要求し、これが私が思いついた最高のxargsソリューションです。ファイル名のスペースが問題である可能性がある場合は、find -execまたはシェルループを使用してください。

関連情報