Answers:
一种方法是:
echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand
假定为a,b并且c不包含空格,换行符,引号或反斜杠。:)
使用GNU,findutil您可以处理一般情况,但是稍微复杂一些:
echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand
您可以取代|一些其他字符分隔符,没有出现在a,b或c。
编辑:正如@MichaelMol所指出的那样,由于参数的列表很长,有可能溢出可传递给的参数的最大长度mycommand。发生这种情况时,最后一个xargs将拆分列表并运行的另一个副本mycommand,因此存在未终止的风险-f。如果您担心这种情况,可以用以下xargs -0类似的内容代替上面的内容:
... | xargs -x -0 mycommand
这不能解决问题,但是mycommand当参数列表过长时,它将中止运行。
mycommand。您可以随时添加-x到最后一个xargs。
xargs,并且只要find可以使用就使用。这种解决方案很危险;您至少应在回答中警告失败案例。
find会有更好的通用解决方案,尤其是当初始参数不是文件名时。:)
-f和一个ls用于说明的示例工具,@ not-a-user处理文件名。给定find提供了-exec参数,它允许您构造命令行,这很好。(只要mycommand允许执行多次即可。如果没有执行,那么使用xargs这里还有另一个问题...)
解决这个问题的更好方法(IMO)是:
在zsh:
l=(a b c)
mycommand -f$^l
或使用数组压缩,以便将参数不附加到该选项:
l=(a b c) o=(-f)
mycommand "${o:^^l}"
这样,如果l数组包含空元素或包含空格的元素或任何其他有问题的字符,它仍然可以工作xargs。例:
$ l=(a '' '"' 'x y' c) o=(-f)
$ printf '<%s>\n' "${o:^^l}"
<-f>
<a>
<-f>
<>
<-f>
<">
<-f>
<x y>
<-f>
<c>在rc:
l=(a b c)
mycommand -f$l在fish:
set l a b c
mycommand -f$l(AFAIK,rc并且fish没有数组压缩)
使用类似Bourne的老式shell bash,您可以始终这样做(仍然允许$@数组元素中的任何字符):
set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"
for i; do args+=('-f' "$i");done; mycommand "${args[@]}"。如果IDK更快,但将2个元素追加到数组似乎应该是O(n),而set循环可能每次都会复制并重新解析累积的arg列表(O(n ^ 2))。
ARG_MAX并-f使其与之分开。