问题
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-grep
as an example)
# 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?
回答1:
Just run the two ack-grep
commands as a compound command; then pipe the results of the compund command. The first compound command defined in man bash
is the parentheses:
(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 current shell environment, so they can impact on your environment. For instance:
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$
回答2:
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.
回答3:
May be something like this:
ack-grep -f --py apps/ > temp && ack-grep -f --js -f media/js >> temp && cat temp | xargs somecommand
回答4:
Yes, use find
. According to the ack-grep
man page those options just look for .py and .js files
find apps/ media/js -type f -name "*.py" -o -name "*.js" -exec somecommand {} +
The +
option to -exec
makes it work just like xargs
but 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.
来源:https://stackoverflow.com/questions/9108181/append-output-of-one-command-to-the-output-of-another-in-a-single-command