For this you just need grep
:
$ grep -vf fileA fileB
DaDa 43 Gk
PkPk 22 Aa
This uses fileA
to obtain the patterns from. Then, -v
inverts the match.
AwkMan addresses very well why you are not matching lines properly. Now, let's see where your solution needs polishing:
Your code is:
for i in `cat FileA`
do
cat FileB | awk '{ if ($1!='$i') print $0_}'>> Result
done
Why you don't read lines with "for" explains it well. So you would need to say something like the described in Read a file line by line assigning the value to a variable:
while IFS= read -r line
do
cat FileB | awk '{ if ($1!='$i') print $0_}'>> Result
done < fileA
Then, you are saying cat file | awk '...'
. For this, awk '...' file
is enough:
while IFS= read -r line
do
awk '{ if ($1!='$i') print $0_}' FileB >> Result
done < fileA
Also, the redirection could be done at the end of the done
, so you have a clearer command:
while IFS= read -r line
do
awk '{ if ($1!='$i') print $0_}' FileB
done < fileA >> Result
Calling awk
so many times is not useful and you can use the FNR==NR
trick to process two files together.
Let's now enter in awk
. Here you want to use some kind of variable to compare results. However, $i
is nothing to awk
.
Also, when you have a sentence like:
awk '{if (condition) print $0}' file
It is the same to say:
awk 'condition' file
Because {print $0}
is the default action to perform when a condition evaluates to true.
Also, to let awk
use a bash variable you need to use awk -v var="$shell_var"
and then use var
internally-
All together, you should say something like:
while IFS= read -r line
do
awk -v var="$line" '$1 != var' FileB
done < fileA >> Result
But since you are looping through the file many times, it will print the lines many, many times. That's why you have to go all the way up to this answer and use grep -vf fileA fileB
.