The 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
The <( ... )
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:[21483501]
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
Related:
Introduction to Named Pipes
Heads and Tails – an earlier posting that uses temporary named pipes for receiving stdin
Process Substitution, Advanced Bash-Scripting Guide
10 comments
Comments feed for this article
March 20, 2008 at 5:21 am
andrew
Thanks for the help this saved me a bit of time.
Andrew
March 21, 2008 at 1:24 am
crashingdaily
I’m happy to hear it was useful.
March 25, 2008 at 6:12 am
miniGeek.org » Changes to Australia’s daylight saving time
[…] https://crashingdaily.wordpress.com/2008/03/06/diff-two-stdout-streams/#comment-316 […]
July 18, 2009 at 5:32 am
Joshua Rogers
Gah, I have the same problem with my OSX box. Sounds like it has something to do with the darwin diff? Is there a fix, or an alternative diff that can be used to do this?
July 18, 2009 at 5:34 am
Joshua Rogers
I’ve found that gdiff (part of macports package diffutils) does this nicely.
$ gdiff -B <( jrun ausduv "show route protocol aggregate terse table inet.0" | grep "/" ) <( jrun ausrdc "show route protocol aggregate terse table inet.0" | grep "/" )
3d2
< * 24.153.150.0/26 A 130 Reject
15d13
< * 67.79.208.0/21 A 130 Reject
July 18, 2009 at 5:52 am
crashingdaily
I don’t recall if I was using OS X 10.4 or an early version of 10.5 when I originally wrote this post, but I just tried with the diff on 10.5.7 and it does work now.
$ diff –version
diff (GNU diffutils) 2.8.1
$ diff <( sort A | tr [:lower:] [:upper:] )
2a3
> HARMONY
January 27, 2012 at 11:50 am
Tobia Tesan
Not only this solved my problem, but reminded me that that Buffy marathon I’m planning is long overdue.
:)
February 19, 2012 at 5:30 pm
In the linux comand line, how can I run two commands and compare the standard output diff? - Quora
[…] add comment if you are logged out. Kevin Ernest Long, Geek at Large Named pipeshttp://crashingdaily.wordpress.c…This answer .Please specify the necessary improvements. Edit Link Text Show answer summary […]
June 6, 2013 at 7:18 am
shell tricks « Lance YAO
[…] https://crashingdaily.wordpress.com/2008/03/06/diff-two-stdout-streams/ […]
November 12, 2021 at 5:12 pm
[小技巧] 使用 diff 命令来比较标准输出 - 算法网
[…] 本文翻译至:https://crashingdaily.wordpress.com/2008/03/06/diff-two-stdout-streams/ […]