我正在寻找一个Bash单行程序,它为列表中的每个项目调用一次函数。例如,给定列表
foo bar baz和程序“cowsay”,它将产生:
_____
< foo >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
_____
< bar >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
_____
< baz >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
(也许中间有其他文字,并不重要)
我知道我可以使用bash脚本执行此操作:
#!/bin/sh
for w in $@; do
cowsay $w
done
但我无法想象没有其他办法可以做到。
编辑:我认为我在最初的问题上并不是很清楚。我希望能够在不编写bash脚本的情况下执行此类操作:locate foo | sed s/bar/baz/ | [other-processing] | [insert-magic-here] cowsay
关键是我正在努力避免编写脚本,这样我就可以将它添加到我的管道链而不考虑它。
答案 0 :(得分:11)
听起来你想要使用xargs。
$ echo foo bar | xargs -n 1 cowsay
_____
< foo >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
_____
< bar >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
答案 1 :(得分:9)
你想要xargs
。如果没有for
,while
或until
循环结构,xargs
就是唯一可以满足您要求的内容。
如果需要xargs为每个输入执行命令,请使用-n1
,而不是将许多输入作为单独的参数执行。你的例子变成了:
$ locate foo | sed s/bar/baz/ | [other-processing] | xargs -n1 cowsay
答案 2 :(得分:5)
在一行中:
for i in foo bar baz; do cowsay $i; done
或者更清楚:
foobar="foo bar baz"
for i in $foobar
do
cowsay $i
done
答案 3 :(得分:1)
正如其他人所说,xargs(1)就是你想要的,但它并不总是合适的。大多数情况下,当它为我失败时,就是我想运行shell函数的时候。 xargs运行可执行命令。
您可以在管道中放置一个循环,而无需将其放在shell脚本中:
$ locate foo | sed s/bar/baz/ | [other-processing] | while read line ; do cowsay "$line" ; done
如果cowsay是一个shell函数,这个管道可以工作,但不能用xargs。
答案 4 :(得分:0)
您可以编写一个将其转换为线条的函数:
function foreach
{
func=$1; shift
for arg in $@; do
${func} ${arg}
done
}
然后调用它:
foreach cosway foo bar baz
答案 5 :(得分:0)
如果您对使用“for”循环不感兴趣,那么迭代字符串列表的其他选项是使用“while”或“until”循环。
您是否希望编写可以按如下方式执行的bash脚本?
$ cowsay-loop foo bar buzz