bash - for loop for IP range excluding certain IPs

20.1k views Asked by At

I have the below for loop

for ip in 10.11.{32..47}.{0..255}
do
        echo "<ip>${ip}</ip>" 
done

I want to exclude this iprange: 10.11.{32..35}.{39..61} from the above for loop. This ip range is a subset of the above one. Is there a way to do that?

I tried this, this doesn't work:

abc=10.11.{34..37}.{39..61}
for ip in 10.11.{32..47}.{0..255}
do
    if [[ $ip == $abc ]]
    then
            echo "not_defined"
    else
            echo "<ip>${ip}</ip>"
    fi
done
2

There are 2 answers

5
Alfe On BEST ANSWER

Try this:

for ip in 10.11.{32..47}.{0..255}
do
        echo 10.11.{32..35}.{39..61} | grep -q "\<$ip\>" && continue
        echo "<ip>${ip}</ip>" 
done

This of course is a simple solution which still loops through the complete set and throws away some unwanted elements. As your comment suggests, this may produce unnecessary delays during the parts which are skipped. To avoid these, you can generate the values in parallel to the processing like this:

for ip in 10.11.{32..47}.{0..255}
do
        echo 10.11.{32..35}.{39..61} | grep -q "\<$ip\>" && continue
        echo "${ip}" 
done | while read ip
do
        process "$ip"
done

If the process "$ip" is taking at least a minimal amount of time, then the time for the generation of the values will most likely not fall into account anymore.

If you want to skip the values completely, you also can use a more complex term for your IPs (but then it will not be clear anymore how this code derived from the spec you gave in your question, so I better comment it thoroughly):

# ranges below result in
# 10.11.{32..47}.{0..255} without 10.11.{32..35}.{39..61}:
for ip in 10.11.{32..35}.{{0..38},{62..255}} 10.11.{36..47}.{0..255}
do
        echo "${ip}" 
done
4
Cyrus On

Try this:

printf "%s\n" 10.11.{32..47}.{0..255} 10.11.{32..35}.{39..61} | sort | uniq -u | while read ip; do echo $ip; done