通过xargs传递多个参数


17

我希望能够用于xargs在命令的不同部分执行多个参数。

例如,以下内容:

echo {1..8} | xargs -n2 | xargs -I v1 -I v2 echo the number v1 comes before v2

我希望它会回来

the number 1 comes before 2
the number 3 comes before 4 

...等等

这可以实现吗?我怀疑我对的多次使用-I是不正确的。

Answers:


29

我相信您不能使用-I这种方式。但是您可以通过以下方式获得所需的效果/行为:

echo {1..8} | xargs -n2 sh -c 'echo "the number $1 comes before $2"' sh

本质上,这将创建一个临时的单行shell脚本,该xargs脚本通过执行sh -cxargs从输入中解析出的两个值将传递到此“脚本”。然后,shell将这些值分配给$1$2,然后可以在“脚本”中引用这些值。


4
谢谢-太好了。我一直在阅读有关sh的内容,并且正在努力理解sh的第二个调用的作用,以及由此扩展的原因,为什么省略它会使结果“减半”。
Damien Sawyer

6
@DamienSawyer没有第二个呼叫sh。最后sh的结尾是要放入的内容$0$0通常包含解释器或脚本名称的内容。
库萨兰达

我刚刚更换尾随shecho $sh它的工作原理。所以最终sh功能是占位符
Kenn

好吧,这是库萨兰南达所说的过分简化了。
斯科特

6

对于的特定情况printf,您始终可以执行以下操作:

echo {1..8} | xargs printf 'the number %s comes before %s\n'

因为如果给定的参数多于一次调用所需的参数,则具有多次执行printf的内在xargs能力。尽管那没有什么优势

printf 'the number %s comes before %s\n' {1..8}

对于大型列表,简单的xargs命令可能会导致xargs运行的多个实例printf,其中一些实例可能具有奇数个参数。你可以传递-n 1000xargs防范的是,其中1000是偶数,应该是足够小,以免到达参数列表太长限制和足够大,以避免运行这么多printf秒。

请注意,每次调用都将在一个单独的新进程中进行,而xargs不是shell的buildin printf进行外部printf调用。

还要注意,对于空输入,除了在某些BSD上,它仍将printf不带参数运行一次。GNU xargs和compatible具有-r (或--no-run-if-empty)选项来避免这种情况。

明确地说,这个简单的答案是特定于您的printf示例的,并且在通常必须一次将两个参数传递给命令的情况下diff(例如,对于)来说是不起作用的。要解决的一般问题zsh,可以使用:

for i j ({1..8}) echo "the number $i comes before $j"

(1)恕我直言,zsh上面的部分是一个真实的答案,xargs-with-no-options部分只是一个奇怪的例子。在这种情况下,我将考虑把真正的答案放在首位。(2)我假设您有理由不在zsh命令中使用引号。如果是这样,您可能要声明一下,以免人们阅读上面的内容并开始认为引用并不重要。(或者简单地包括它们,因为它们不会造成伤害。)
斯科特(Scott

这真的很酷。我登陆这里寻找类似的地方,但我不确定我要接收多少个参数,这些参数必须放入下一个参数的命令行中。做了类似的事情awk -F'\t' '/match/{printf $1"\0"$2"\0"}' | xargs -0 printf -- '-args1 "%s" -args2 "%s"' | xargs mycommand
keithpjolley

@keithpjolley,您-0在第一个xargs使它更可靠的用法被击败,因为您没有在第二个使用它。此外,第一个参数printf(包括独立的效用和awkprintf()函数)的格式,你不应该使用变量存在。在这里,您可以做awk -F'\t' '/match/{printf "-args1\0%s\0-args2\0%s\0", $1, $2}' | xargs -n400 -r0 mycommand。同样,-n400需要确保xargs传递的参数是4的倍数。(请注意,并非所有awk实现都支持使用\0此处的参数)。
斯特凡Chazelas

没用过-0使它更可靠,而是用它来做我想做的事。
keithpjolley,

2

尝试这个:

echo {1..8} |xargs -n 2 bash -c 'echo "the number $0 comes before $1"'

2
在这种情况下可以使用,但是最好在中sh -c使用sh(或其他任何方式)运行脚本$0。请注意,如果脚本要使用它$0,则不包括在内,例如,脚本是$@sh -cecho "the two numbers were $@"
Kusalananda
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.