Reputation: 2586
There are several unix commands that are designed to operate on two files. Commonly such commands allow the contents for one of the "files" to be read from standard input by using a single dash in place of the file name.
I just came across a technique that seems to allow both files to be read from standard input:
comm -12 <(sort file1) <(sort file2)
My initial disbelieving reaction was, "That shouldn't work. Standard input will just have the concatenation of both files. The command won't be able to tell the files apart or even realize that it has been given the contents of two files."
Of course, this construction does work. I've tested it with both comm
and diff
using bash 3.2.51 on cygwin 1.7.7. I'm curious how and why it works:
Upvotes: 16
Views: 7859
Reputation: 360153
Bash, Korn shell (ksh93, anyway) and Z shell all support process substitution. These appear as files to the utility. Try this:
$ bash -c 'echo <(echo)'
/dev/fd/63
$ ksh -c 'echo <(echo)'
/dev/fd/4
$ zsh -c 'echo <(echo)'
/proc/self/fd/12
You'll see file descriptors similar to the ones shown.
Upvotes: 12
Reputation: 54744
This is a standard Bash extension. <(sort file1)
opens a pipe with the output of the sort file1
command, gives the pipe a temporary file name, and passes that temporary file name on the comm
command line.
You can see how it works by getting echo
to tell you what's being passed to the program:
echo <(sort file1) <(sort file2)
Upvotes: 6