Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I want merge (union) output from two different commands, and pipe them to a single command.

A silly example:

Commands I want to merge the output:

cat wordlist.txt
ls ~/folder/*

into:

wc -l

In this example, if wordlist.txt contains 5 lines and 3 files, I want wc -l to return 8.

$cat wordlist.txt *[magical union thing]* ls ~/folder/* | wc -l
8

How do I do that?

share|improve this question
add comment

2 Answers 2

up vote 8 down vote accepted

Your magical union thing is a semicolon... and curly braces:

    { cat wordlist.txt ; ls ~/folder/* ; } | wc -l

The parenthesis are only grouping the commands together, so that the pipe sign | affects the combined output.

You can also use parenthesis () around a command group, which would execute the commands in a subshell. This has a subtle set of differences with curly braces, e.g. try the following out:

    cd $HOME/Desktop ; (cd $HOME ; pwd) ; pwd
    cd $HOME/Desktop ; { cd $HOME ; pwd ; } ; pwd

You'll see that all environment variables, including the current working directory, are reset after exiting the parenthesis group, but not after exiting the curly-brace group.

As for the semicolon, alternatives include the && and || signs, which will conditionally execute the second command only if the first is successful or if not, respectively, e.g.

    cd $HOME/project && make
    ls $HOME/project || echo "Directory not found."
share|improve this answer
    
That does work! Help me learn - what exactly are the curly braces doing in here? What other magical powers do they have? –  David Oneill May 7 '12 at 19:13
    
@DavidOneill { list; } is a compound command. From bash(1): list is simply executed in the current shell environment. list must be terminated with a newline or semicolon. [..] The return status is the exit status of list. –  Lekensteyn May 7 '12 at 19:18
    
I've added a bit more info to the answer. The definitive guide to shell scripting with bash is the bash manpage, type man bash from the command line and browse it. –  pablomme May 7 '12 at 19:24
    
should the ; in those commands not be && in case the file wordlist.txt does not exists? –  Rinzwind May 7 '12 at 19:33
    
If wordlist.txt does not exist an error from cat will appear on standard error, but not on standard output, so wc -l will not count any lines from it. Same goes for ~/folder not existing. One could add 2> /dev/null between each of these commands and their semicolon to prevent noise on standard error, but other than being ugly, error messages are harmless for the purpose of counting lines. –  pablomme May 7 '12 at 19:39
show 2 more comments

Since wc accepts a file path as input, you can also use process substitution:

wc -l <(cat wordlist.txt; ls ~/folder/*)

This roughly equivalent to:

echo wordlist.txt > temp
ls ~/folder/* >> temp
wc -l temp

Mind that ls ~/folder/* also returns the contents of subdirectories if any (due to glob expansion). If you just want to list the contents of ~/folder, just use ls ~/folder.

share|improve this answer
    
The wc -l was just a made up example, i'm actually piping it into something more complicated that doesn't have this option. –  David Oneill May 7 '12 at 19:12
1  
@DavidOneill Well, as cat accepts a file argument, you can use cat <(cat wordlist.txt; ls wordlist.txt) | wc -l and even cat wordlist.txt <(ls wordlist.txt) | wc -l. This is of course very ugly, but it demonstrates the endless possibilities with command line tools. –  Lekensteyn May 7 '12 at 19:14
    
Ah, I see what you mean. Thanks! –  David Oneill May 7 '12 at 19:23
    
@DavidOneill Correct, I've corrected it now, thanks. –  Lekensteyn May 7 '12 at 19:25
    
You want ls ~/folder/ so that if ~/folder is a symbolic link ls lists the contents of its target instead of the link itself. By the way, all the ls commands should be followed by -1 so that a single file per line is printed and wc -l is a valid way of counting files. –  pablomme May 7 '12 at 20:28
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.