I'd like to print a list of lines where the first word in two files is identical, and the rest of the words are not. Some complicated mess with comm, grep and cut would be possible, but hopefully there's a simpler way.

Edit: I've managed to slap together some working code. Example tests:

$ cat file1
a 1 E
b 2 F
c 3 G

$ cat file2
a M X
b 2 Y
c 3 G

$ difff 1 file1 file2 # Differences in fields 2+3
< a 1 E
< b 2 F
> a M X
> b 2 Y

$ difff 1-2 file1 file2 # Differences in field 3 only
< b 2 F
> b 2 Y

Edit 2: The speed is now bearable (compares two files of 1800 and 8700 lines in half a second).

  • 1
    Is there some reason why a traditional (or unified) diff won't do the job?
    – draeath
    Sep 19 '11 at 16:19
  • Are the first columns of file1 and file2 identical? Have you considered join and paste? (I'm not going to offer more precise suggestion because I don't understand the requirements.) Sep 19 '11 at 23:56
  • @draeath: Because if would also show lines which start with different words. That's what I want to exclude. As you can see from the diff above, the lines starting with baz and bay are not included, even though they are different.
    – l0b0
    Sep 20 '11 at 6:40

Assuming that both file1 and file2 are sorted (otherwise join won't work):

diff -u file1 file2 |
  grep -E "^[+-]($(echo $(join -o0 file1 file2) | tr ' ' '|'))"


The join command will output the join field that occurs in both files (i.e. the first word of the line which is the same in both files), one on each line. We echo this though tr, replacing all spaces with a pipe (|). The reason for doing the slightly convoluted echo (and not just piping the result from join directly through tr) is that the output from join will have a newline at the end of it which we do not want to replace with a pipe.

For the example files (the ones that were originally given by the OP before his edit of the question), the join, echo, tr thingy will produce bar|foo. This is the used as part of an extended regular expression in grep -E to filter through the output of diff -u.

The output of the command line is:

-bar c d
+bar x y
  • Didn't use join, but your answer pointed in the right direction.
    – l0b0
    Sep 20 '11 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.