awk
is a better tool for comparing columns of files. See, for example, the answer to: compare two columns of different files and print if it matches -- there are similar answers out there for printing lines for matching columns.
Since you want to print lines that don't match, we can create an awk
command that prints the lines in file2 for which column 2 has not been seen in file1:
$ awk 'NR==FNR{c[$2]++;next};c[$2] == 0' file1 file2
Another 193 stuff2
Another 783 stuff3
As explained similarly by terdon in the above-mentioned question,
NR==FNR
: NR is the current input line number and FNR the current file's line number. The two will be equal only while the 1st file is being read.
c[$2]++; next
: if this is the 1st file, save the 2nd field in the c
array. Then, skip to the next line so that this is only applied on the 1st file.
c[$2] == 0
: the else block will only be executed if this is the second file so we check whether field 2 of this file has already been seen (c[$2]==0
) and if it has been, we print the line. In awk
, the default action is to print the line so if c[$2]==0
is true, the line will be printed.
But you also want the lines from file1 for which column 2 doesn't match in file2. This you can get by simply exchanging their position in the same command:
$ awk 'NR==FNR{c[$2]++;next};c[$2] == 0' file2 file1
Something 456 item2
Something 768 item3
So now you can generate the output you want, by using awk
twice. Perhaps someone with more awk
expertise can get it done in one pass.
You tagged your question with /ksh
, so I'll assume you are using korn shell. In ksh
you can define a function for your diff, say diffcol2
, to make your job easier:
diffcol2()
{
awk 'NR==FNR{c[$2]++;next};c[$2] == 0' $2 $1
awk 'NR==FNR{c[$2]++;next};c[$2] == 0' $1 $2
}
This has the behavior you desire:
$ diffcol2 file1 file2
Something 456 item2
Something 768 item3
Another 193 stuff2
Another 783 stuff3