Reputation: 13
My goal is to take a list of IPs, sometimes the list is just a single IP or it could be a range of IPs and count how many IPs there are in a list. We have another product that generates a list of IPs and we have been manually counting it using an Excel spreadsheet.
Using an existing post here on Stack, I have been attempting to incorporate it into a script that will accept a list. https://codegolf.stackexchange.com/questions/28760/how-many-ip-addresses-are-in-a-given-range (See Pure Bash, 66 bytes).
Instead of grabbing two arguments on the command line $1 and $2, I pull a list into an array then enumerate through the array. If it is a single IP, it just adds 1 to the counter variable, if it is a range it uses the logic to convert the IPs to hex and counts them. I'm running into an issue where I am receiving errors.
I can't seem to figure out why this says "invalid number: printf: 229". I've read up on the expansion principle and I cannot seem to get my head around why it keeps throwing this error and calculating it improperly.
I've used this site for years, this is my first post. Any help would be greatly appreciated!
Thank you!
This is what I have so far:
#!/bin/bash
if [ $# -lt 1 ]; then
echo "Please supply a list of IP addresses"
echo "Example: " $0 "list.txt"
exit
fi
#Set some variables
LIST=($(cat ./$1))
COUNT=0
# Function for removing dots and converting to hex
p()(printf %02x ${1//./ })
# Enumerate the array of IPs
for RANGE in ${LIST[@]};do
IFS=- read IP1 IP2 <<< $RANGE
if [ -z $IP2 ]; then
COUNT=$[COUNT + 1]
else
r=$[0x`p $IP1`-0x`p $IP2`]
COUNT=$[COUNT + $[1+${r/-}]]
fi
done
echo "The count is" $COUNT
sample_range.txt:
192.168.47.11
192.168.48.10
192.168.65.228-192.168.65.229
192.168.65.234
192.168.65.239
192.168.65.241
192.168.65.244
192.168.80.220
192.168.93.231-192.168.93.235
192.168.93.237-192.168.93.239
192.168.103.222
This should result in 18, instead it gives me this output:
# ./rc.sh sample_range.txt
: invalid number: printf: 229
: invalid number: printf: 235
: invalid number: printf: 239
The count is 707
Upvotes: 1
Views: 1359
Reputation: 88939
IPs are numbers base 256.
#!/bin/bash
ipdiff() {
declare -i dec1 dec2 diff # set integer attribute
dec1=$1*256*256*256+$2*256*256+$3*256+$4
dec2=$5*256*256*256+$6*256*256+$7*256+$8
diff=$dec2-$dec1+1
counter=counter+$diff
}
declare -i counter
# read IP(s) from file, use . and - as separator
while IFS=".-" read -r a1 a2 a3 a4 b1 b2 b3 b4; do
if [[ -z $b1 ]]; then # $b1 is empty (line with one IP)
counter=counter+1
else # $b1 is not empty (line with 2 IPs)
ipdiff $a1 $a2 $a3 $a4 $b1 $b2 $b3 $b4
fi
done < file
echo $counter
Output:
18
Upvotes: 1