$ echo 1.2.3.4 | awk -F. -v OFS=. 'NF==1{print ++$NF}; NF>1{if(length($NF+1)>length($NF))$(NF-1)++; $NF=sprintf("%0*d", length($NF), ($NF+1)%(10^length($NF))); print}'
1.2.3.5
1.2.3.9 => 1.2.4.0
1.2.3.44 => 1.2.3.45
1.2.3.99 => 1.2.4.00
1.2.3.999=> 1.2.4.000
1.2.9 => 1.3.0
999 => 1000
UPDATE:
#!/usr/bin/gawk -f
BEGIN{
v[1] = "1.2.3.4"
v[2] = "1.2.3.44"
v[3] = "1.2.3.99"
v[4] = "1.2.3"
v[5] = "9"
v[6] = "9.9.9.9"
v[7] = "99.99.99.99"
v[8] = "99.0.99.99"
v[9] = ""
for(i in v)
printf("#%d: %s => %s\n", i, v[i], inc(v[i])) | "sort | column -t"
}
function inc(s, a, len1, len2, len3, head, tail)
{
split(s, a, ".")
len1 = length(a)
if(len1==0)
return -1
else if(len1==1)
return s+1
len2 = length(a[len1])
len3 = length(a[len1]+1)
head = join(a, 1, len1-1)
tail = sprintf("%0*d", len2, (a[len1]+1)%(10^len2))
if(len2==len3)
return head "." tail
else
return inc(head) "." tail
}
function join(a, x, y, s)
{
for(i=x; i<y; i++)
s = s a[i] "."
return s a[y]
}
$ chmod +x inc.awk
$ ./inc.awk
#1: 1.2.3.4 => 1.2.3.5
#2: 1.2.3.44 => 1.2.3.45
#3: 1.2.3.99 => 1.2.4.00
#4: 1.2.3 => 1.2.4
#5: 9 => 10
#6: 9.9.9.9 => 10.0.0.0
#7: 99.99.99.99 => 100.00.00.00
#8: 99.0.99.99 => 99.1.00.00
#9: => -1