99

I have two files:

file 1

dsf
sdfsd
dsfsdf

file 2

ljljlj 
lkklk 
dsf
sdfsd
dsfsdf

I want to display what is in file 2 but not in file 1, so file 3 should look like

ljljlj 
lkklk 
vehomzzz
  • 42,832
  • 72
  • 186
  • 216

11 Answers11

166
grep -Fxvf file1 file2

What the flags mean:

-F, --fixed-strings
              Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.    
-x, --line-regexp
              Select only those matches that exactly match the whole line.
-v, --invert-match
              Invert the sense of matching, to select non-matching lines.
-f FILE, --file=FILE
              Obtain patterns from FILE, one per line.  The empty file contains zero patterns, and therefore matches nothing.
dogbane
  • 266,786
  • 75
  • 396
  • 414
61

You can try

grep -f file1 file2

or

grep -v -F -x -f file1 file2
jopasserat
  • 5,721
  • 4
  • 31
  • 50
krico
  • 5,723
  • 2
  • 25
  • 28
47

You can use the comm command to compare two sorted files

comm -13 <(sort file1) <(sort file2)
dogbane
  • 266,786
  • 75
  • 396
  • 414
  • 3
    FYI, it is actually `comm -1 -3 file1 file2`. The two flags `1` and `3` are merged into one. – cevaris Feb 19 '15 at 20:30
  • comm -23 <(sort file1) <(sort file2) will output only those in file1 and not in file2 -- the best part of this is any arrangement in file2 works where diff will fail; say file1 has 1,2,3,4,5 and file2 has 1,2,4,5 you get 3 diff will get it wrong – user1213320 Mar 31 '17 at 03:07
14

I successfully used

diff "${file1}" "${file2}" | grep "<" | sed 's/^<//g' > "${diff_file}"

Outputting the difference to a file.

Luca Borrione
  • 16,324
  • 8
  • 52
  • 66
  • What better way to find differences than to use a diff tool haha. Is there higher overhead with using this versus grep? – Allison Jul 31 '17 at 15:26
9

if you are expecting them in a certain order, you can just use diff

diff file1 file2 | grep ">"

Nate
  • 12,499
  • 5
  • 45
  • 60
7
join -v 2 <(sort file1) <(sort file2)
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
4

A tried a slight variation on Luca's answer and it worked for me.

diff file1 file2 | grep ">" | sed 's/^> //g' > diff_file

Note that the searched pattern in sed is a > followed by a space.

Community
  • 1
  • 1
3
file1 
m1
m2
m3

file2 
m2
m4
m5

>awk 'NR == FNR {file1[$0]++; next} !($0 in file1)' file1 file2
m4
m5

>awk 'NR == FNR {file1[$0]++; next} ($0 in file1)' file1 file2
m2

> What's awk command to get 'm1 and m3' ??  as in file1 and not in file2? 
m1
m3
Chals
  • 141
  • 1
  • 3
1

an awk answer:

awk 'NR == FNR {file1[$0]++; next} !($0 in file1)' file1 file2

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
0

With GNU sed:

sed 's#[^^]#[&]#g;s#\^#\\^#g;s#^#/^#;s#$#$/d#' file1 | sed -f- file2

How it works:

The first sed produces an output like this:

/^[d][s][f]$/d
/^[s][d][f][s][d]$/d
/^[d][s][f][s][d][f]$/d

Then it is used as a sed script by the second sed.

Jahid
  • 21,542
  • 10
  • 90
  • 108
0

If you want to use loops You can try like this: (diff and cmp are much more efficient. )

while read line
do
    flag = 0
    while read line2
    do
       if ( "$line" = "$line2" )
        then
            flag = 1
        fi
     done < file1 
     if ( flag -eq 0 )
     then
         echo $line > file3
     fi
done < file2

Note: The program is only to provide a basic insight into what can be done if u dont want to use system calls such as diff n comm..

letsc
  • 2,075
  • 5
  • 24
  • 43