user3897784
user3897784

Reputation:

How to get grep -F -f to find lines missing from one file in another

First I create two files:

echo -en {1..100..3}"\n" > file1; echo -en {1..100..5}"\n" > file2

then

grep -v -F -f file1 -- file2 >> file3; cat file3 >> file1; rm file3

then

grep -v -F -f file2 -- file1 >> file3; cat file3 >> file2; rm file3

both grep -v -F -f file1 -- file2 and grep -v -F -f file2 -- file1 return nothing

yet numbers like 13, 19, 64, 67, 100 are still only in file1, why?

if you look at the output of grep -v -F -f file1 -- file2 and grep -v -F -f file2 -- file1 before the merge attempt those numbers are also missing

If i use something like IFS=$(echo -en "\n\b") && for a in $(cat <file 1>); do ((\!$(grep -F -c -- "$a" <file 2>))) && echo $a; done && unset IFS it works.

Update the answer is add -x flag to grep for anchoring, thanks to Tripleee:

$ echo -en {1..100..3}"\n" > file1; echo -en {1..100..5}"\n" > file2
$ grep -x -v -F -f file1 -- file2 >> file3; cat file3 >> file1; rm file3
$ grep -x -v -F -f file2 -- file1 >> file3; cat file3 >> file2; rm file3
$ grep 13 *

file1: 13 file2: 13

before without

$ echo -en {1..100..3}"\n" > file1; echo -en {1..100..5}"\n" > file2
$ grep -v -F -f file1 -- file2 >> file3; cat file3 >> file1; rm file3
$ grep -v -F -f file2 -- file1 >> file3; cat file3 >> file2; rm file3
$ grep 13 *

file1: 13

Upvotes: 1

Views: 782

Answers (2)

Tensibai
Tensibai

Reputation: 15784

Using -w to tell grep to compare words achieve a correct merge.

I did test like this with your exemple files:

grep -v -w -f file1 file2 >> file1
grep -v -w -f file2 file1 >> file2
grep -v -w -f file1 file2

To be sure I sorted the files:

sort -h file1 > f1
sort -h file2 > f2

thend a diff -u f1 f2 giving nothing I ensured it was correct with diff -y f1 f2

If you can elaborate on your use case I may improve this answer.

Just in case of, as you're talking about lines in the tittle, the -x flag instead of -w could be what you're looking for.

Upvotes: 1

tripleee
tripleee

Reputation: 189387

Without anchoring, grep will find a match whenever a search pattern is a substring of an input. Add the -x option to change that. Then a match will only be reported when the pattern matches the entire input line.

Upvotes: 0

Related Questions