41

I would like to get (GNU)DIFF to printout only lines that are different in one file. So given

    ==> diffa.txt <==
    line1
    line2 - in a only
    line3
    line4 changed
    line5

    ==> diffb.txt <==
    line1
    line3
    line4 changed in b
    line5
    line6 in b only

i would like diff --someoption diffa.txt diffb.txt to produce

    line2 - in a only

    line4 changed

The following looks as though it should be helpful but it is a bit cryptic :

   --GTYPE-group-format=GFMT
          Similar, but format GTYPE input groups with GFMT.

   --line-format=LFMT
          Similar, but format all input lines with LFMT.

   --LTYPE-line-format=LFMT
          Similar, but format LTYPE input lines with LFMT.

   LTYPE is `old', `new', or `unchanged'.
          GTYPE is LTYPE or `changed'.

          GFMT may contain:

   %<     lines from FILE1

   %>     lines from FILE2
2
  • 1
    The man page is definitely a bit terse on these flags! Good question. Oct 18, 2013 at 0:01
  • 2
    I would like to point out that ' info diff ' will give complete examples, there is a wealth of information in info. Jul 6, 2016 at 17:24

3 Answers 3

53

Not sure diff alone can do it but you can always use the power of other GNU utilities to help you.

diff -u diffa.txt diffb.txt | grep '^-[^-]' | sed 's/^-//'

It does the diff, then selects only the lines that begins with '-' - those are changed and have values from diffa.txt file, then sed just remove those '-' signs.

Edit: After few experiments with diff, looks like the below command produces what you want:

diff --changed-group-format='%<' --unchanged-group-format='' diffa.txt diffb.txt
2
  • For a one off the pipe method is fine. I would prefer ` perl -ne"print if s/^-//" ` but that is taste. I think I see what --changed-group-format='%<' are doing for me now....
    – justintime
    Apr 27, 2010 at 14:08
  • Thanks. :D I needed something like this to list all my packages between two computers and I used sdiff but this looks a bit better.
    – Rob
    Sep 21, 2011 at 14:34
17

More simple method is to use comm linux utility (It needs sorted file for input). It writes to standard output:

  • lines that are unique for diffa.txt

  • lines that are unique for diffb.txt

  • lines that are common

and you can suppress each one of them by parameter 1,2 or 3 accordingly. So in youre case it will look like this :

comm -23 diffa.txt diffb.txt

It suppresses lines that are unique for diffb.txt, lines that are common and prints out lines that are unique only for diffa.txt

Source from:https://www.tutorialspoint.com/unix_commands/comm.htm

2
  • I found this a lot easier than diff which isn't doing what I expect. And I believe it's preinstalled both on BSD (i.e. Mac OS X) as well as Ubuntu so no package manager nightmares. May 3, 2017 at 6:19
  • If diffa.txt and diffb.txt are not already sorted, we can do the following: comm -23 <(sort diffa.txt) <(sort diffb.txt)
    – Jea
    Jul 22, 2022 at 13:08
6

I'd like to mention that comm expects sorted input files and thus reports different results than diff.

diff --changed-group-format='%<' --unchanged-group-format='' diffa.txt diffb.txt

is universal. Kudos to @vava

1
  • This is a very useful remark.
    – user93692
    Mar 25, 2020 at 17:43

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.