Here are a few bits for you. First, a script in Bash, so not very efficient. It doesn't do exactly what you want, because it only checks one pair of subnets and reports the overlap. Below the script a few rough shell commands follow, thought the result is not presented in the form you want. So you need to integrate and adjust the whole bunch to your needs, or treat them as a sketch illustrating the logic.
#!/usr/bin/env bash
subnet1="$1"
subnet2="$2"
# calculate min and max of subnet1
# calculate min and max of subnet2
# find the common range (check_overlap)
# print it if there is one
read_range () {
IFS=/ read ip mask <<<"$1"
IFS=. read -a octets <<< "$ip";
set -- "${octets[@]}";
min_ip=$(($1*256*256*256 + $2*256*256 + $3*256 + $4));
host=$((32-mask))
max_ip=$(($min_ip+(2**host)-1))
printf "%d-%d\n" "$min_ip" "$max_ip"
}
check_overlap () {
IFS=- read min1 max1 <<<"$1";
IFS=- read min2 max2 <<<"$2";
if [ "$max1" -lt "$min2" ] || [ "$max2" -lt "$min1" ]; then return; fi
[ "$max1" -ge "$max2" ] && max="$max2" || max="$max1"
[ "$min1" -le "$min2" ] && min="$min2" || min="$min1"
printf "%s-%s\n" "$(to_octets $min)" "$(to_octets $max)"
}
to_octets () {
first=$(($1>>24))
second=$((($1&(256*256*255))>>16))
third=$((($1&(256*255))>>8))
fourth=$(($1&255))
printf "%d.%d.%d.%d\n" "$first" "$second" "$third" "$fourth"
}
range1="$(read_range $subnet1)"
range2="$(read_range $subnet2)"
overlap="$(check_overlap $range1 $range2)"
[ -n "$overlap" ] && echo "Overlap $overlap of $subnet1 and $subnet2"
The usage and result are these:
$ ./overlap.bash 194.33.26.0/26 194.33.24.0/22
Overlap 194.33.26.0-194.33.26.63 of 194.33.26.0/26 and 194.33.24.0/22
Now given your first list of subnets is in file list and the subnets to check are in the file to_check, you can use the script to find all overlaps.
$ while read l; do list+=("$l"); done < list
$ while read t; do to_check+=("$t"); done < to_check
$ for i in "${list[@]}"; do for j in "${to_check[@]}"; do \
./overlap.bash "$i" "$j"; done; done
This is the result:
Overlap 194.33.26.0-194.33.26.63 of 194.33.24.0/22 and 194.33.26.0/26
Overlap 188.115.195.88-188.115.195.95 of 188.115.195.80/28 and 188.115.195.88/29
Overlap 41.202.219.32-41.202.219.63 of 41.202.219.32/27 and 41.202.219.0/24
Overlap 41.202.219.128-41.202.219.135 of 41.202.219.128/29 and 41.202.219.0/24
Overlap 41.202.219.208-41.202.219.223 of 41.202.219.208/28 and 41.202.219.0/24
Overlap 41.202.219.136-41.202.219.143 of 41.202.219.136/29 and 41.202.219.0/24
Overlap 197.157.209.128-197.157.209.143 of 197.157.209.0/24 and 197.157.209.128/28
As you can see, 41.202.219.0/24 has four overlaps, contrary to your expectations in your question.
To get only the subnets with no overlaps with the first list, the script would be much shorter. You don't need the to_octets function and the check_overlap function can already give result on this line:
if [ "$max1" -lt "$min2" ] || [ "$max2" -lt "$min1" ]; then return; fi
Also the last two lines can can be changed (with the last one removed completely).
As for the integration logic, there's place for short-circuiting the checking against the first list, as not all combinations have to be checked. One negative is enough.