Industry guru Dave Taylor answers free tech support questions about a wide variety of business and technical topics, including blogging, Google AdSense, MySpace, Sony PSP, Apple iPod, Mp3 players, management, Linux, SEO, Mac OS X, Facebook, Twitter, LinkedIn and Microsoft Windows.

How do I increment IP addresses in a shell script?

I need help with a shell script! I want to prompt someone to enter an IP address the automatically increment it and output the sequence of that address and its following addresses, but I don't know how to do that: when I try to increment a value like "10.10.10.27" it fails because it's not a number.


Dave's Answer:

You've realized the problem already, you just need to think slightly out of the box to figure out the solution. That is, if an IP address isn't a number from the perspective of the shell, you need to break it up so that it is.

But first, a quick primer: IP (v4, at least) addresses are comprised of four decimal values, each ranging from 0 to 255. Effectively, however, 0 and 255 are typically reserved for routers, loopback addresses, etc, so really you'll want to range from 1-254 (but that's easy to tweak anyway).

A given IP address is therefore four numeric values all strung together with dot separators: 10.10.10.27. What the script needs to do is split the address back up, which can be done a number of different ways, but I'll use the cut command since I can specify what field separator to use:

baseaddr="$(echo $ip | cut -d. -f1-3)"
lsv="$(echo $ip | cut -d. -f4)"

(I'm using "lsv" to represent the least significant value here).

With this snippet of code, you'll have the following two values set:

baseaddr = 10.10.10
lsv = 27

That's perfect. Now you can step through your loop incrementing the "lsv" variable until you hit your MaxValue (254 or 255), regardless of where you start.

Here's my full version of your script:

#!/bin/sh

MaxValue=255 # highest valid IP octet value

echo -n "Enter IP address: "; read ip
echo -n "How many IP addresses do you need: "; read count

baseaddr="$(echo $ip | cut -d. -f1-3)"
lsv="$(echo $ip | cut -d. -f4)"

while [ $count -gt 0 ]
do
if [ $lsv -eq $MaxValue ] ; then
# here you'll need to increment the third level IP value,
# but that might cascade into the second, or the first.
# consider the case of 17.255.255.255 + 1
echo "edge case needs to be written"
fi
echo $baseaddr.$lsv
lsv=$(( $lsv + 1 ))
count=$(( $count - 1 ))
done

exit 0

Note that there's an important edge condition that needs to be written, which will actually make this script quite a bit more complex. The situation you need to tackle is what happens when the IP address rolls past the MaxValue?

If you have 10.10.10.255 then the next value can't be 10.10.10.256 because that's no longer a valid IP address, but rather 10.10.11.0. Doable, but you'll probably end up needing to break the IP address into all four octets rather than just the first three as a monolithic value and the fourth as the incrementing value.

But I'll leave that part of this homework assignment to you. :-)



Help others find this article at Del.icio.us, Digg, Netscape, Reddit, and Simpy.

Subscribe!

Never miss another useful Q&A article again! Subscribe to AskDaveTaylor with Google Reader.

Comments

The one given by Dave is a nice one :-) .

Without considering the decimal of last octet exceeding the max value 255 (as Dave stated above)
I got a very small one liner for that: (my one is not taking care of that)

[jsaikia@zorro trap]$ cat ips.con
172.22.22.11
192.168.32.6
172.18.1.121
172.20.21.21
[jsaikia@zorro trap]$ for ip in `cat ips.con`; do echo $ip | awk -F "." '{print $1"."$2"."$3"."$4+1}'; done
172.22.22.12
192.168.32.7
172.18.1.122
172.20.21.22

Posted by: Jadu at February 26, 2007 10:42 PM

I have a lot to say, but ...
Starbucks coffee cup I have a lot to say, and questions of my own for that matter, but most of all I'd like to say thank you for all your efforts on this Web site by buying you a chai!

I do have a comment, now that you mention it!









Remember personal info?


Please note that I will never send you any unsolicited commercial email. Ever.

While I'm at it, please note that by submitting a question or comment you're agreeing to my terms of service, which are: you relinquish any subsequent rights of ownership to your material by submitting it on this site.









Search
Find just the answers you seek from among our 1700+ free tech support articles by using our Lijit search engine.


Help!





Subscribe to
Ask Dave Taylor!

Add to Google Reader
Add to My Yahoo!
Subscribe in NewsGator Online

RDF   XML

Free Updates!
Sign up and get free weekly updates and special offers on books, seminars, workshops and more.


Recent Entries
Join the List!
Join my author info mailing list, where you'll learn about my upcoming books, speaking gigs, and more!


Book Links
© 2002 - 2008 by Dave Taylor. All Rights Reserved.

Note: This web site is for the purpose of disseminating information for educational purposes, free of charge, for the benefit of all visitors. We take great care to provide quality information. However, we do not guarantee, and accept no legal liability whatsoever arising from or connected to, the accuracy, reliability, currency or completeness of any material contained on this web site or on any linked site.

[whiteboard marker tray]