Though the grep
answer works for you, sort
and uniq
can do the trick also.
Assuming you have the construct <(command)
available (e.g. use bash).
The construct will be replaced by a temporary file, containing the output of command
.
This will work, with your example:
sort <(uniq new) old | uniq -u
Though more general would be:
sort <(uniq new) old old | uniq -u
Which also works if the old
file contains lines that are not in new
.
What happens is, that first the new
file gets it duplicate lines removed. (This assumes that duplicates in the new
file are adjacent. Otherwise replace <(uniq new)
by <(sort -u new)
.)
Then the output of sort ...
is taken as input to uniq -u
.
uniq -u
prints lines that are occurring only once.
Because the old
file is presented twice to the sort ...
command, none of the lines in old
will make it to the output of uniq -u
.
Also any lines common between old
and new
will not be present.
sort
and uniq
can be combined in several ways to perform mathematical set operations:
Set union: f U g
sort f g | uniq
Set intersection: f ∩ g
sort f g | uniq -d ## uniq -d
only prints duplicate lines
Set difference: f \ g
sort f g g | uniq -u ## uniq -u
only prints unique lines
Note that the files f
and g
represent sets. So they must not have duplicate lines. If that is not the case, replace e.g. f
by <(sort -u f)
.