Xargs
具有多個命令和 max-args 的 xargs
我有一個程序需要任意數量的文件。它像
./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
輸入實際上分為三個文件組。
但是,當我使用帶有“I”選項的更多命令的 xargs 時,它只傳遞給 ./code 文件 1:
ls file* | xargs -n3 -I {} sh -c './code output.txt {}; command2; command3'
你能指出我做錯了什麼嗎?
不要
{}
用作腳本文本的一部分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
,並用於該 shell 產生的任何錯誤消息(它不是 的一部分"$@"
)。在
zsh
外殼中(但不在 egbash
或中sh
),您可以改為for name1 name2 name3 in file*; do ./code output.txt $name1 $name2 $name3 command2 command3 done
有關的: