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:
- Space before
[
- Dollar before
(
- Semicolon before
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