bash - for loop for IP range excluding certain IPs
Solution 1
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
Solution 2
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
Comments
-
spacemtn5 almost 2 years
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
-
Etan Reisner almost 9 yearsAre you asking if you can get the brace expansion to do that for you or are you asking how to write the logic in the loop to exclude those ranges?
-
-
Sato Katsura almost 9 yearsSadly this doesn't eliminate anything. You could try something like this instead:
... | sort | uniq -c | awk '$1 = 1 { print $2 }' | ...
-
Cyrus almost 9 years@SatoKatsura: Can't reproduce this with bash version 4.3.11.
printf
create 4188 lines and| sort | uniq -u
reduce it to 4004 lines. -
spacemtn5 almost 9 yearsThis is great Alfe, but we are still looping thru the ip range 10.11.{32..35}.{39..61} (which we wanted to exclude) but not printing the output. Please correct me if I am wrong. I was planning on adding an "if condition" inside the "for loop" to exclude the ip range 10.11.{32..35}.{39..61}. I have a bunch of other commands to be included inside the for loop, not just echo. I'm planning to save time by not hitting this ip-range, just not printing the output will not help.
-
Alfe almost 9 yearsNormally whatever you do in these loops will take much more time than the looping itself, but I see your point and will do my best to address this. Stay tuned.
-
Alfe almost 9 yearsAdded some more versions.
-
spacemtn5 almost 9 yearsAlfe, Thank you sir. This looks great but you mentioned that the origin will not be visible anymore. Which origin are you talking about?
-
Alfe almost 9 yearsYou are right, this was unclear. I rephrased the answer there to explain in more detail and more clearly what I mean.
-
Alfe almost 9 yearsDidn't know the option
-u
foruniq
yet. Thanks for that hint! -
spacemtn5 almost 9 yearsCyrus, Your solution is awesome too. Just modified yours at the sort, that would have been perfect. printf "%s\n" 10.11.{32..47}.{0..255} 10.11.{32..35}.{39..61} | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n | uniq -u | while read ip; do echo $ip; done
-
Cyrus almost 9 years@spacemtn5: Thank you for this hint.