bash: how do I concatenate the output of two commands so that I can pipe them to a third?

19,039

Solution 1

You can use a subshell:

( hg status; hg status --ignored ) | awk '( $1 == "?" ) || ( $1 == "I") { print $2 }' | xargs rm -r

Solution 2

Use curly braces to group commands:

$ { echo first line; echo second line; } | grep "line"
first line
second line

(Posted as an answer from camh's comment)

Solution 3

You can use the rest of the hg status flags to show what you really want:

hg status -uriamn

That shows unknown files (u), removed files (r), ignored (i), added (a), modified (m) and does so without showing the status prefix.

Solution 4

This works for me:

echo $(a)$(b)

if you add "" you can add delimiters eg.:

echo "$(./gethostname.sh)|($(./getip.sh);"

I use this on Openwrt to broadcast my ip settings:

echo "$( uci get system.@system[0].hostname )|$( ip addr | grep inet | grep br-lan | cut -d ' ' -f 6 | cut -d '/' -f 1 );"  | socat - UDP-DATAGRAM:255.255.255.255:4999,broadcast ;
Share:
19,039

Related videos on Youtube

John Lawrence Aspden
Author by

John Lawrence Aspden

Programmer/Contractor/Consultant in Cambridge UK Lover of LISP, C and Unix. Friend of Python and ML. CV: http://www.aspden.com Clojure Blog: http://www.learningclojure.com Random Thoughts: http://johnlawrenceaspden.blogspot.com

Updated on June 07, 2020

Comments

  • John Lawrence Aspden
    John Lawrence Aspden about 4 years
    $ hg status
    

    and

    $ hg status --ignored
    

    give very similar outputs. I'd like to concatenate them so I can feed them to awk, as if there were an hg status --all (or svn's svn status --no-ignore)

    I'm thinking something like:

    $ echo "$(hg status)" "$(hg status --ignored)" | awk  ' ( $1 == "?" ) || ( $1 == "I") { print $2 }' | xargs rm -r
    

    to make a 'make very clean indeed' command, but it seems to occasionally leave a file behind, perhaps because a newline goes missing or something.

    • Fred Foo
      Fred Foo almost 13 years
      If you replace rm with echo (or skip the last pipe), then what is the output and what should it have been? Also, there might be permission issues where rm refuses to delete a file.
  • Kent
    Kent almost 13 years
    +1 I just wrote down "why not try hg st -iu|awk ...?" and saw your answer shows up...
  • camh
    camh almost 13 years
    There's no need to use a subshell (another process). Instead you can use braces to group: { a; b; } | c
  • Ben Moss
    Ben Moss almost 13 years
    And I would have posted sooner, but I was trying to make an amusing anagram out of the flags ;-)
  • Mark Fox
    Mark Fox over 8 years
    I see no meaningful speed difference time { git branch; git branch -r; } > /dev/null; time (git branch; git branch -r) > /dev/null in fact subshell is consistently faster on my system — so @camh, what is is the advantage of a group?
  • camh
    camh over 8 years
    @MarkFox: It's likely measurement error. The group has one less fork() than the subshell. It is very hard to measure a single run of things like this. You want to run it 1000 times or more to get a good feel for the performance. When I do that, the group comes out at 1.69s and the subshell at 2.36s, which is about 40% slower.
  • Aaron Wallentine
    Aaron Wallentine about 7 years
    Excellent, thank you. This is what I was looking for, trying to concatenate headers to pass to sendmail -t along with output of another command.