If the files given are sorted and there are no internal duplicates, use this:
$ comm -12 a.txt <(sed 's/\.[^.]*$//' up.txt) | comm -23 - <(sed 's/\.[^.]*$//' dw.txt)
In shells that have Process Substitution (<(…)
). For other shells read below.
What you describe in this sentence:
get the lines from a.txt that exists in b.txt and not in c.txt
could be reduced to the set operations:
( a intersect b ) complement c
There are several ways to execute set operations on files, many are listed on this answer
I like the way the command comm
could perform most operations.
But the files you present are not the clean set to use. The extensions need to be erased/removed. The generic way to remove the extensions with sed is:
$ sed 's/\.[^.]*$//' file
So, the two clean files will be created with:
$ sed 's/\.[^.]*$//' up.txt > up.txt.clean
$ sed 's/\.[^.]*$//' dw.txt > dw.txt.clean
With those two files, a one-liner solution is:
$ comm -12 a.txt up.txt.clean | comm -23 - dw.txt.clean
c
Or, doing ( up.txt complement dw.txt) intersect a.txt
:
$ comm -23 up.txt.clean dw.txt.clean | comm -12 - a.txt
c
Both commands could be implemented directly from original files in some shells with:
$ comm -12 a.txt <(sed 's/\.[^.]*$//' up.txt) | comm -23 - <(sed 's/\.[^.]*$//' dw.txt)
If the process substitution is not available it is possible to use only one file as follows:
$ sed 's/\.[^.]*$//' up.txt | comm -12 a.txt - >result1.txt
$ sed 's/\.[^.]*$//' dw.txt | comm -23 result1.txt -
c
$ rm result1.txt
kdiff3
is a visual tool, not for streaming/scripts, there are other diff tools, includingdiff
). a 3way diff tool will do best. – ctrl-alt-delor Jul 08 '18 at 15:52