diff utility reports differences between two files. If you need to find differences between one or two stdout outputs then temporary named pipes are a handy aid.
Here’s a simple example for the BASH shell to illustrate the technique. Say you have two files, A and B:
$ cat A Tara Dawn Anya Willow $ cat B WILLOW ANYA DAWN HARMONY TARA
The task is to find names that differ between the two lists without creating new files or editing the existing. You can do that by sorting and normalizing the letter case, then using diff to check the stdout on the fly.
$ diff -B <( sort A | tr [:lower:] [:upper:] ) <( sort B | tr [:lower:] [:upper:] ) 2a3 > HARMONY
<( ... ) syntax creates a temporary named pipe which makes the stdout of the
sort | tr commands look and behave like a file, allowing
diff to operate on the expected type of input.
For fun, you can see the temporary file created by the process:
dir <( sort A | tr [:lower:] [:upper:] ) lr-x------ 1 crash daily 64 Mar 5 23:17 /dev/fd/63 -> pipe:
This technique is not limited to
diff. This should work for most any other command expecting a file for input.
Interestingly (frustratingly), it does not work for me in my BASH shell on Mac OS X. Does anyone know why? Update: Indeed someone does know. Unixjunkie has the answer. The following produces the expected output
on OS X but attempting
diff produces no output.
cat <( sort A | tr [:lower:] [:upper:] ) <( sort B | tr [:lower:] [:upper:] ) ANYA DAWN TARA WILLOW ANYA DAWN HARMONY TARA WILLOW
Introduction to Named Pipes
Heads and Tails – an earlier posting that uses temporary named pipes for receiving stdin
Process Substitution, Advanced Bash-Scripting Guide