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
使其与之分开。