bash 如何将 shell 命令应用于命令输出的每一行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2711001/
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-09 19:14:15  来源:igfitidea点击:

How to apply shell command to each line of a command output?

bash

提问by Alex Budovski

Suppose I have some output from a command (such as ls -1):

假设我有一些命令的输出(例如ls -1):

a
b
c
d
e
...

I want to apply a command (say echo) to each one, in turn. E.g.

我想echo依次对每个命令(比如)应用一个命令。例如

echo a
echo b
echo c
echo d
echo e
...

What's the easiest way to do that in bash?

在 bash 中最简单的方法是什么?

回答by Michael Mrozek

It's probably easiest to use xargs. In your case:

这可能是最容易使用的xargs。在你的情况下:

ls -1 | xargs -L1 echo

The -Lflag ensures the input is read properly. From the man page of xargs:

-L标志确保正确读取输入。从手册页xargs

-L number
    Call utility for every number non-empty lines read. 
    A line ending with a space continues to the next non-empty line. [...]

回答by Trey Hunner

You can use a basic prepend operation on each line:

您可以在每一行上使用基本的前置操作:

ls -1 | while read line ; do echo $line ; done

Or you can pipe the output to sed for more complex operations:

或者您可以将输出通过管道传输到 sed 以进行更复杂的操作:

ls -1 | sed 's/^\(.*\)$/echo /'

回答by Michael Aaron Safyan

You can use a for loop:

您可以使用for 循环

for file in * ; do
   echo "$file"
done

Note that if the command in question accepts multiple arguments, then using xargsis almost always more efficient as it only has to spawn the utility in question once instead of multiple times.

请注意,如果有问题的命令接受多个参数,那么使用xargs几乎总是更有效,因为它只需要生成有问题的实用程序一次而不是多次。

回答by ?ukasz Daniluk

You actually canuse sed to do it, provided it is GNU sed.

您实际上可以使用 sed 来执行此操作,前提是它是 GNU sed。

... | sed 's/match/command 
for s in `cmd`; do echo $s; done
/e'

How it works:

这个怎么运作:

  1. Substitute match with command match
  2. On substitutionexecute command
  3. Replace substituted line with command output.
  1. 用命令匹配替换匹配
  2. 在替换执行命令
  3. 用命令输出替换替换的行。

回答by Marcelo Cantos

cmd | xargs -L1 echo

If cmd has a large output:

如果 cmd 有大输出:

ls -1 |tr \n \0 |xargs -0 -iTHIS echo "THIS is a file."

回答by phil294

xargs fails with with backslashes, quotes. It needs to be something like

xargs 失败并带有反斜杠、引号。它需要像

-0, --null
          Input  items are terminated by a null character instead of by whitespace, and the quotes and backslash are
          not special (every character is taken literally).  Disables the end of file string, which is treated  like
          any  other argument.  Useful when input items might contain white space, quote marks, or backslashes.  The
          GNU find -print0 option produces input suitable for this mode.

xargs -0 option:

xargs -0 选项:

-0, --null
          Input  items are terminated by a null character instead of by whitespace, and the quotes and backslash are
          not special (every character is taken literally).  Disables the end of file string, which is treated  like
          any  other argument.  Useful when input items might contain white space, quote marks, or backslashes.  The
          GNU find -print0 option produces input suitable for this mode.
ls -l | gawk '{system("/path/to/cmd.sh ")}'

ls -1terminates the items with newline characters, so trtranslates them into null characters.

ls -1用换行符终止项目,因此tr将它们转换为空字符。

This approach is about 50 times slower than iterating manually with for ...(see Michael Aaron Safyans answer) (3.55s vs. 0.066s). But for other input commands like locate, find, reading from a file (tr \\n \\0 <file) or similar, you have to work with xargslike this.

这种方法比手动迭代慢约 50 倍for ...(参见Michael Aaron Safyan的回答)(3.55s 与 0.066s)。但是对于其他输入命令,例如定位、查找、读取文件 ( tr \\n \\0 <file) 或类似命令,您必须xargs像这样使用。

回答by Chris

i like to use gawk for running multiple commands on a list, for instance

例如,我喜欢使用 gawk 在列表上运行多个命令

ls -1 | xargs -L1 -d "\n" CMD

however the escaping of the escapable characters can get a little hairy.

然而,转义可转义字符的转义可能会有点麻烦。

回答by Andrej Pandovich

Better result for me:

对我来说更好的结果:

##代码##