Xargs

具有多個命令和 max-args 的 xargs

  • August 6, 2019

我有一個程序需要任意數量的文件。它像

./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的將被放入腳本$0sh -c,並用於該 shell 產生的任何錯誤消息(它不是 的一部分"$@")。

zsh外殼中(但不在 egbash或中sh),您可以改為

for name1 name2 name3 in file*; do
   ./code output.txt $name1 $name2 $name3
   command2
   command3
done

有關的:

引用自:https://unix.stackexchange.com/questions/534104