在 bash 中执行 for-each

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1697706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 21:23:06  来源:igfitidea点击:

Executing for-each in bash

bash

提问by perimosocordiae

I'm looking to write a Bash one-liner that calls a function once for each item in a list. For example, given the list

我正在寻找编写一个 Bash one-liner,为列表中的每个项目调用一次函数。例如,给定列表

foo bar baz
和程序“cowsay”,它将产生:

 _____
< foo >
 -----
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
 _____
< bar >
 -----
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
 _____
< baz >
 -----
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

(Maybe with additional text in between, doesn't really matter)

(也许中间有额外的文字,并不重要)

I know I can do this with a bash script:

我知道我可以用 bash 脚本做到这一点:

#!/bin/sh

for w in $@; do
  cowsay $w
done

But I can't imagine that there isn't another way to do it.

但我无法想象没有其他方法可以做到这一点。

EDIT: I wasn't very clear in my initial question, I think. I want to be able to do something like this without writing a bash script:

编辑:我认为我最初的问题不是很清楚。我希望能够在不编写 bash 脚本的情况下做这样的事情:

locate foo | sed s/bar/baz/ | [other-processing] | [insert-magic-here] cowsay

The point is that I'm trying to avoid having to write a script, so that I can just add it to my pipe chain and not think about it.

关键是我试图避免编写脚本,这样我就可以将它添加到我的管道链中而不去考虑它。

回答by Nicholas Riley

Sounds like you want to use xargs then.

听起来你想使用 xargs 。

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

回答by quack quixote

You want xargs. Without a for, while, or untilloop structure, xargsis about the only thing that will do what you ask.

你要xargs。没有for, while, 或until循环结构,xargs是唯一可以满足您要求的事情。

Use -n1if you need xargs to execute your command for each input, instead of executing with many inputs as separate arguments. Your example becomes:

使用-n1,如果你需要xargs的为每个输入执行你的命令,而不是用很多投入作为单独的参数执行。你的例子变成:

$ locate foo | sed s/bar/baz/ | [other-processing] | xargs -n1 cowsay

回答by Kimmo Puputti

In one line:

在一行中:

for i in foo bar baz; do cowsay $i; done

Or more clearly:

或者更清楚:

foobar="foo bar baz"

for i in $foobar
do
    cowsay $i
done

回答by camh

As other's have said, xargs(1) is what you want, but it is not always suitable. Most often when it has failed for me, it was when I wanted to run a shell function. xargs runs an executable command.

正如其他人所说, xargs(1) 是您想要的,但并不总是合适的。大多数情况下,当它对我来说失败时,是当我想运行一个 shell 函数时。xargs 运行一个可执行命令。

You can put a loop in your pipeline without needing to put it in a shell script:

您可以在管道中放置一个循环,而无需将其放入 shell 脚本中:

$ locate foo | sed s/bar/baz/ | [other-processing] | while read line ; do cowsay "$line" ; done

If cowsay was a shell function, this pipeline would work, but not with xargs.

如果 cowsay 是一个 shell 函数,这个管道可以工作,但不能与 xargs 一起使用。

回答by R Samuel Klatchko

You could write a function that turns this into a liner:

您可以编写一个将其转换为班轮的函数:

function foreach
{
    func=; shift
    for arg in $@; do
        ${func} ${arg}
    done
} 

And then invoke it like:

然后像这样调用它:

foreach cosway foo bar baz

回答by jkndrkn

If you are not interested in using a "for" loop, then your other options to iterate over a list of strings is to use a "while" or "until" loop.

如果您对使用“for”循环不感兴趣,那么遍历字符串列表的其他选项是使用“while”或“until”循环。

Is it the case that you are wanting to write a bash script that can be executed as follows?

是不是想写一个可以执行如下的bash脚本?

$ cowsay-loop foo bar buzz

$ cowsay-loop foo bar buzz