Compare two data streams without both being stored as files

command-substitution

I have these two files:-

[root@localhost base_filters]# cat aix_old
joe
amadeus
image
bill
juliet
charlie
romeo
ftp


[root@localhost base_filters]# cut -d: -f1 passwd2
henry
amadeus
image
bill
julie
jennifer
charlie
romeo
harry

I am trying to find out the differences between two files; so I am using the following command:-

[root@localhost base_filters]# cut -d: -f1 passwd2 | sort | diff `sort aix_old` -

But getting this following error:

diff: extra operand `charlie'
diff: Try `diff --help' for more information.

I know I can use another temporary file for sorting the contents in aix_old but I don't want another temporary file; so tried with command substitution.

Any idea, what I might be doing wrong.

Best Answer

With ksh, zsh or bash, using process substitution:

diff <(cut -d: -f1 passwd2 | sort) <(sort aix_old)

gives:

4,5c4
< harry
< henry
---
> ftp
7,8c6,7
< jennifer
< julie
---
> joe
> juliet
diff -y <(cut -d: -f1 passwd2 | sort) <(sort aix_old)

gives:

amadeus                              amadeus
bill                                bill
charlie                             charlie
harry                                 | ftp
henry                                 <
image                               image
jennifer                              | joe
julie                                 | juliet
romeo                               romeo

From the process substition wiki: http://en.wikipedia.org/wiki/Process_substitution

The Unix diff command normally accepts the names of two files to compare, or one file name and standard input. Process substitution allows you to compare the output of two programs directly:

$ diff <(sort file1) <(sort file2)

The <(command) expression tells the command interpreter to run command and make its output appear as a file. The command can be any arbitrarily complex shell command.

The same using yash's process redirection (on systems with /dev/fd/n):

diff /dev/fd/3 3<(cut -d: -f1 passwd2 | sort) /dev/fd/4 4<(sort aix_old)

Or more cumbersomely with any Bourne-like shell (on systems with /dev/fd/n):

cut -d: -f1 passwd2 | sort | {
  sort aix_old 3<&- | diff /dev/fd/3 -
} 3<&0