任意の数のファイルを必要とするプログラムがあります。それは次のように動作します
./code output.txt file1 file2 file3
何千もの入力ファイル(file1、file2、...、file1000)があります。
しかし、
入力ファイルを複数のコレクションに分割できます。たとえば、2つの後続の入力ファイルを結合します。
./code output.txt file1 file2
./code output.txt file3 file4
...
(コードを呼び出すたびにoutput.txtが追加されます。)または後続の3つの入力ファイルを結合します。
./code output.txt file1 file2 file3
./code output.txt file4 file5 file6
...
役に立つものを見つけましたxargs
。
ls file* | xargs -n3
入力は実際には3つのファイルグループに分けられます。
ただし、「I」オプションでxargsコマンドを使用すると、ファイル1のみが./codeに渡されます。
ls file* | xargs -n3 -I {} sh -c './code output.txt {}; command2; command3'
私が間違っていることを指摘してもらえますか?
答え1
スクリプトテキスト{}
の一部として使用しないでくださいsh -c
(この問題は許可された回答に記載されている問題と似ています)「find -exec sh -c」を使っても安全ですか?)。
代わりに:
printf '%s\n' file* | xargs -n 3 sh -c './code output.txt "$@"; command2; command3' sh
ファイル名に改行文字が含まれていない場合は機能します。xargs
非標準-0
オプション(最も一般的な実装)がある場合、次は改行のあるファイル名でも機能します。
printf '%s\0' file* | xargs -0 -n 3 sh -c './code output.txt "$@"; command2; command3' sh
(引用文"$@"
は重要)はスクリプト内の位置パラメータのリストに展開されますsh -c
。これはスクリプトで指定されたファイル名ですxargs
。sh
役に立たないように見える最後の内容はスクリプトに挿入され、その$0
シェルsh -c
(の一部ではない"$@"
)によって生成されたエラーメッセージに使用されます。
zsh
シェルで(たとえば、またはbash
ではないsh
)、次のことができます。
for name1 name2 name3 in file*; do
./code output.txt $name1 $name2 $name3
command2
command3
done
関連: