1

I am a bit rusty on my scripting abilities and am trying to find a good starting point for creating a script that creates files (generating new file names) and edits the IP address in the file by incrementing it by +1

My scenario is like so - We have about 50 IP addresses to add to our network-scripts each with an incrementing IP. I could do this by hand, however I thought this would be a good time to try and get up to speed on my scripting skills.

The naming scheme is like so:

ifcfg-eth0:1, ifcfg-eth0:2, ifcfg-eth0:3 ...*n*

The content of these files is:

DEVICE=eth0:1
NETMASK=255.255.255.0
IPADDR=10.2.7.148
BOOTPROTO=none
ONBOOT=yes
DNS1=10.2.53.150
PEERDNS=yes
DNS2=10.2.53.250
GATEWAY=10.2.7.1
TYPE=Ethernet
USERCTL=no
IPV6INIT=no

Where IPADDR=10.2.7.148 should be increased by +1 in each file.

For example: ifcfg-eth0:2 file would be the exact same except that the IPADDR would be 10.2.7.149 and so on.

I am fairly certain I should invoke sed to find and replace the IP addresses.

For instance, searching for an IP address using sed could be accomplished like so:

sed -rn '/(IPPADDR=)((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])/p' file

What steps need to be taken to generate a new file with the eth0:N name incremented by +1 as well as the IP address in the file.

Thanks in advance!

EDIT: Let me clarify the names of the files should not contain the IP address.

I am needing file1 to be copied over to file2 eth0:1 -> eth0:2 with same file contents as above, except the fact that the IPADDR= field on the generated file should be incremented by one.

Note: The file name should also be incremented by +1 IE. cp ifcfg-eth0:1 ifcfg-eth0:2

  • Im not sure how you can implement it but using the redirection operators would be a good start to creating the file. If you use the following command: sed -rn '/IPPADDR=)((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])/p' file >> newFile – ryekayo Nov 18 '14 at 20:18
1

As far as I'm aware of sed cannot do calculations on numbers, I would use awk

$ awk -F'.' '$1~"IPADDR"{$NF++;OFS="."}1' file
DEVICE=eth0:1
NETMASK=255.255.255.0
IPADDR=10.2.7.149
BOOTPROTO=none
ONBOOT=yes
DNS1=10.2.53.150
PEERDNS=yes
DNS2=10.2.53.250
GATEWAY=10.2.7.1
TYPE=Ethernet
USERCTL=no
IPV6INIT=no

Include this into a loop of files to be changed.


Explanation:

  • -F'.': use . a field separator
  • $1~"IPADDR"{}: if first field contains IPADDR pattern run what is inside{}
  • $NF++;OFS=".": increment number in last field (NF denotes number of fields in the record).
  • 1: print everything
  • This is very helpful - I will be able to use this to change/replace the IP portion of the file. What I can do is copy the previous file over using bash and incrementing the file name then run this awk command over the newly generated file, all in the same script. Care to explain what is going on here in this command? I would also need to increment the DEVICE=eth0:X portion. But if I understand this I would probably be able to adapt it. – Christopher Stanley Nov 18 '14 at 21:03
  • @Christopher see the updated edit for explanation. – jimmij Nov 18 '14 at 21:23
  • What about ip finishing with .255 ? – Gilles Quenot Nov 18 '14 at 22:26
  • You are asking me? OP wants to increase the value so it will be 256. Whether is has any sense is another story. It is of course very simple to add if condition, but I don't know what should desired action in such case look like (back to 0, or increase previous number .X.255, or ...) – jimmij Nov 18 '14 at 22:33
  • Theoretically you can implement numerical calculations in sed, but this involves doing things like s/1\(+.*\)1$/0\12/ and a zillion similar replacements to implement additions. So in practice, indeed, you can't do arithmetic in sed, and awk is the right tool for this job if the configuration file template is passed as input (another sensible method being to embed the template in the shell script). – Gilles Nov 19 '14 at 0:46
1

I don't know if I've understood you correctly. Does this do what you want?

Bash:

[root@domain]:test # IP=120
[root@domain]:test # for i in {1..50}; do
> echo "IP=10.11.11.$IP
> NETMASK=255.255.255.0
> DEVICE=eth0:1
> ONBOOT=yes
> DNS1=10.2.53.150
> PEERDNS=yes
> DNS2=10.2.53.250
> GATEWAY=10.2.7.1
> TYPE=Ethernet
> USERCTL=no
> IPV6INIT=no" >> ifcfg-eth0:$i; IP=$((IP+1)); done;

Result:

[root@domain]:test # ls ifcfg* |wc -l
50
[root@domain]:test # grep IP= ifcfg*
ifcfg-eth0:1:IP=10.11.11.120
...
ifcfg-eth0:50:IP=10.11.11.169
0

With :

$ perl -ne '
    s/^(IPADDR=10\.2\.7\.)(\d+)/$2 < 255 and sprintf "%s%s", $1, $2 + 1/e;
    print
' file

Output:

DEVICE=eth0:1
NETMASK=255.255.255.0
IPADDR=10.2.7.149
BOOTPROTO=none
ONBOOT=yes
DNS1=10.2.53.150
PEERDNS=yes
DNS2=10.2.53.250
GATEWAY=10.2.7.1
TYPE=Ethernet
USERCTL=no
IPV6INIT=no

You can add -i switch to modify the file in-place.

  • This helps a lot (along with the awk suggestion above) - I think I can utilize this portion in the script to make the changes to the IP address and use bash to generate the new file names. – Christopher Stanley Nov 18 '14 at 20:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.