Show only matched lines - grep
I have two files. File1 looks like this
Apple
Cat
Bat
File2 looks like this
I have an Apple
Batman returns
This is a test file.
Now I want to check which lines in the first file are missing in the second file. I can do grep -f file1 file2
, but it gives me consistent lines in the second file.
source to share
To get the lines in the first file as well as in the second file :
grep -of file1 file2
The result (using this example) will be:
Apple Bat
To get the lines in the first file but not in the second file , you can:
grep -of file1 file2 | cat - file1 | sort | uniq -u
Or even simpler (thanks @triplee comment):
grep -of file1 file2 | grep -vxFf - file1
The result (using this example) will be:
Cat
From the grep
man page :
-o , - match only
Print only the matched (non-blank) portions of the matching line, each on a separate output line.
From the uniq
man page :
-u , - unique
Print only unique lines
source to share
If you want to show words from file1 that are not in file2, the dirty way is to skip the words and grep silently. If there is a mismatch, type the word:
while read word
do
grep -q "$word" f2 || echo "$word"
done < f1
To match exact words add -w
: grep -wq
...
Test
$ while read word; do grep -q "$word" f2 || echo "$word"; done < f1
Cat
$ while read word; do grep -wq "$word" f2 || echo "$word"; done < f1
Cat
Bat
The best approach is to use awk:
$ awk 'FNR==NR {a[$1]; next} {for (i=1;i<=NF;i++) {if ($i in a) delete a[$i]}} END {for (i in a) print i}' f1 f2
Cat
Bat
Saves the values in file1 to an array a[]
. It then iterates over all the lines of file2, checking every single item. If one of them matches the value in the array a[]
, then that element is removed from the array. Finally, the block END{}
prints the values that were not found.
source to share