在bash中执行for-each

时间:2009-11-08 19:55:12

标签: bash

我正在寻找一个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

关键是我正在努力避免编写脚本,这样我就可以将它添加到我的管道链而不考虑它。

6 个答案:

答案 0 :(得分:11)

听起来你想要使用xargs。

$ echo foo bar | xargs -n 1 cowsay
 _____
< foo >
 -----
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
 _____
< bar >
 -----
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

答案 1 :(得分:9)

你想要xargs。如果没有forwhileuntil循环结构,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