bash 在单个命令中将一个命令的输出附加到另一个命令的输出

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

Append output of one command to the output of another in a single command

bashunixstdoutpipe

提问by dheerosaur

Is there a way to append the stdout output of one command to another's and pipe the combined output to another command? I used to use the following approach(taking ack-grepas an example)

有没有办法将一个命令的 stdout 输出附加到另一个命令并将组合输出通过管道传输到另一个命令?我曾经使用以下方法(以ack-grep为例)

# List all python, js files in different directories
ack-grep -f --py apps/ > temp
ack-grep -f --js -f media/js >> temp
cat temp | xargs somecommand

Is there a way to do this in a single command?

有没有办法在单个命令中做到这一点?

回答by James Polley

Just run the two ack-grepcommands as a compound command; then pipe the results of the compund command. The first compound command defined in man bashis the parentheses:

只需将这两个ack-grep命令作为复合命令运行即可;然后通过管道传输复合命令的结果。中定义的第一个复合命令man bash是括号:

   (list) list is executed in a subshell environment (see  COMMAND  EXECU-
              TION  ENVIRONMENT below).  Variable assignments and builtin com-
              mands that affect the  shell's  environment  do  not  remain  in
              effect  after  the  command completes.  The return status is the
              exit status of list.

So:

所以:

james@bodacious-wired:tmp$echo one > one.txt
james@bodacious-wired:tmp$echo two > two.txt
james@bodacious-wired:tmp$(cat one.txt; cat two.txt) | xargs echo
one two

You can use curly braces to similar effect, but curly braces have a few syntactical differences (they're more finicky about needing spaces between the brace and other words, for instance). The biggest difference is that the commands inside braces are run in the currentshell environment, so they can impact on your environment. For instance:

您可以使用大括号达到类似的效果,但大括号在语法上有一些差异(例如,它们对需要在大括号和其他单词之间使用空格更加挑剔)。最大的区别是大括号内的命令是在当前shell 环境中运行的,因此它们可能会影响您的环境。例如:

james@bodacious-wired:tmp$HELLO=world; (HELLO=MyFriend); echo $HELLO
world
james@bodacious-wired:tmp$HELLO=world; { HELLO=MyFriend; }; echo $HELLO
MyFriend

If you want to get really fancy you can define a function and execute that:

如果你想变得真正花哨,你可以定义一个函数并执行它:

james@bodacious-wired:tmp$myfunc () (
> cat one.txt
> cat two.txt
> )
james@bodacious-wired:tmp$myfunc | xargs echo
one two
james@bodacious-wired:tmp$

回答by Blagovest Buyukliev

Group the two commands in curly braces and pipe them:

将这两个命令放在花括号中并用管道输送它们:

{ ack-grep -f --py apps/; ack-grep -f --js -f media/js; } | xargs somecommand

This way you omit the creation of any files.

这样您就可以省略任何文件的创建。

回答by anubhava

May be something like this:

可能是这样的:

ack-grep -f --py apps/ > temp && ack-grep -f --js -f media/js >> temp && cat temp | xargs somecommand

回答by SiegeX

Yes, use find. According to the ack-grepman page those options just look for .py and .js files

是的,使用find. 根据ack-grep手册页,这些选项只查找 .py 和 .js 文件

find apps/ media/js -type f -name "*.py" -o -name "*.js" -exec somecommand {} +

The +option to -execmakes it work just like xargsbut with the benefit that it doesn't die a horrible death if you have files with spaces or newlines or other nasties in their name.

使它像这样工作的+选项,但好处是,如果您的文件名称中包含空格或换行符或其他讨厌的东西,它不会死于可怕的死亡。-execxargs