Reputation: 125
I am trying to write a shell script to simulate the following problem:
File A contains some entries like
a
b
c
and File B contains
a
g
d
t
q
c
the final file should have
(contents of file b which are not there in file a)
g
d
t
q
I was trying something like this but it's not working:
for i in `cat b` ; do if[ (grep $i a) != $i ] then echo $i; done
Upvotes: 0
Views: 115
Reputation: 67301
pearl.260> cat file3
i
a
b
c
pearl.261> cat file4
a
g
d
t
q
c
pearl.262> nawk 'FNR==NR{a[$1];next}!($1 in a)' file3 file4
g
d
t
q
pearl.263>
Upvotes: 0
Reputation: 202
You code has some errors:
forgot the closure of if statement : fi
"grep $i a" must be interpreted as a command , such as $(grep $i a) or `grep $i a`
You must add some characters around $(grep $i a) avoid empty string comparasion , such as ":" or something else, whatever.
Solution:
for i in `cat b` ; do if [ :$(grep $i a) != :$i ] ;then echo $i;fi; done
Upvotes: 2
Reputation: 755016
Sort the files and then use comm
. In bash
:
comm -13 <(sort a) <(sort b)
This assumes you have a sufficiently recent bash
(version 3.2 on Mac OS X 10.7.3 is not new enough; 4.1 is OK), and that your files are a
and b
. The <(sort a)
is process substitution; it runs sort
on a
and the output is sent to comm
as the first file; similarly for <(sort b)
. The comm -13
option suppresses the lines only in the first file (1
, aka a
) and in both files (3
), thus leaving the lines only in 2
or b
.
Your command:
for i in `cat b` ; do if[ (grep $i a) != $i ] then echo $i; done
shows a number of problems — four separate syntactic issues:
[
(
echo
fi;
before done
Fixing them gives:
for i in `cat b`; do if [ $(grep $i a) != $i ]; then echo $i; fi; done
You could also use:
for i in `cat b`
do
if grep $i a > /dev/null
then : in both files
else echo $i
fi
done
Upvotes: 2
Reputation: 57690
Assuming A
and B
is your files, it can be done by diff
diff A B | grep '^>' | cut -d ' ' -f 2-
Upvotes: 1