我有一个程序需要任意数量的文件。它的工作原理就像
./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 命令时,它只会将文件 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
,并在该 shell 生成的任何错误消息中使用(它不是 的一部分"$@"
)。
在zsh
shell 中(但不是在 egbash
或 中sh
),你可以这样做
for name1 name2 name3 in file*; do
./code output.txt $name1 $name2 $name3
command2
command3
done
有关的: