Bobby Eickhoff
Bobby Eickhoff

Reputation: 2586

Redirecting two files to standard input

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

Answers (2)

Dennis Williamson
Dennis Williamson

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

Tim Robinson
Tim Robinson

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

Related Questions