0

I am going to upgrade my network from 64 to 128 IPs. Of course I don't want to change it manually on all 40+ VMs. I plan to use an ansible ad-hoc command with sed -i and then use the same to restart the interfaces. I have tried but and I have found - thank you guys - a solution how to replace the slash in the address, but I still need to carry the last octet of the IP address as a variable into the output. This here works but only partially

Original Text:

address 195.23.154.X/26

What I want:

 address 195.34.154.X/25

in /etc/network/interfaces/

My partially-working sed command with escaped slashes:

 sed 's/address\ 195.24.153.3\/26/address\ 195.23.154.4\/27/g' interfaces.bak

How do I keep the '3' in this example?

3
  • I have read this before but I don't think I understand how it would work in my case. Apr 14 at 10:31
  • Why do you need to need to put the whole IP in the pattern anyhow? You could simply do s_/26_/27_ and use an address to apply the command only to the correct line: sed '/address 195.24.153/s_/26_/27_'
    – Philippos
    Apr 21 at 11:19
  • @Philippos see the follow-up question ;-) Apr 21 at 12:42

2 Answers 2

0

Just replace all slashes that are part of the sed command syntax with a different charcter and keep the slashes that are part of your pattern or replacement, e.g.

sed 's#foo/bar#foo/baz#'

Another option is to escape all slashes that are part of your strings

sed 's/foo\/bar/foo\/baz/'
0

Assuming you actually need to match the string address explicitly, followed by the first three parts of the IP address literally, and then update the subnet mask from /26 to /25:

sed 's|\(address 195\.23\.154\.[0-9]*\)/26|\1/25|'

I'm, first of all, using | as a delimiter for the s/// command. I do this to avoid having to escape the slashes. Any single character can be used as the delimiter in the substitution command (apart from a small number of obvious ones, like newline).

I then capture the first part of the string that matches up to the slash in the address, using \(...\) (note that I need to escape the dots in the expression to be able to match only literal dots in those locations). I'm then able to insert this using a back-reference, \1, in the replacement part of the command.

Since I also captured the last part of the IP address, naively matched by [0-9]*, this will be carried over unchanged to the replacement.

Testing:

$ echo 'address 195.23.154.112/26' | sed 's|\(address 195\.23\.154\.[0-9]*\)/26|\1/25|'
address 195.23.154.112/25

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.