Intersection of two lists in Bash
BashBash Problem Overview
I'm trying to write a simple script that will list the contents found in two lists. To simplify, let's use ls as an example. Imagine "one" and "two" are directories.
one=one=ls one
two=ls two
intersection $one $two
two=one=one=ls one
two=ls two
intersection $one $two
two=ls two
intersection $one $two
intersection $one $two
I'm still quite green in Bash, so feel free to correct how I am doing this. I just need some command that will print out all files in "one" and "two". They must exist in both. You might call this the "intersection" between "one" and "two".
Bash Solutions
Solution 1 - Bash
comm -12 <(ls 1) <(ls 2)
Solution 2 - Bash
Solution with comm
comm
is great, but indeed it needs to work with sorted lists. And fortunately here we use ls
which from the ls
Bash man page:
> Sort entries alphabetically if none of -cftuSUX nor --sort.
comm -12 <(ls one) <(ls two)
Alternative with sort
Intersection of two lists:
sort <(ls one) <(ls two) | uniq -d
Symmetric difference of two lists:
sort <(ls one) <(ls two) | uniq -u
Bonus
Play with it ;)
cd $(mktemp -d) && mkdir {one,two} && touch {one,two}/file_{1,2}{0..9} && touch two/file_3{0..9}
Solution 3 - Bash
Use the comm
command:
ls one | sort > /tmp/one_list
ls two | sort > /tmp/two_list
comm -12 /tmp/one_list /tmp/two_list
"sort" is not really needed, but I always include it before using "comm" just in case.
Solution 4 - Bash
A less efficient (than comm) alternative:
cat <(ls 1 | sort -u) <(ls 2 | sort -u) | uniq -d
Solution 5 - Bash
Join is another good option depending on the input and desired output
join -j1 -a1 <(ls 1) <(ls 2)