1

I've an input file that consists of IP Address and subnet masks. As an example,

1.example.com,10.135.10.111,255.255.255.0,some comment
2.example.com,10.135.10.112,255.255.255.0,some comment
3.example.com,10.135.10.113,255.255.255.0,some comment
4.example.com,10.135.10.11,255.255.255.0, some comment
10.135.10.111 A 
10.135.10.112 A
10.135.10.113 A
10.135.10.11  A

I loop the IP address in my bash script and when using the perl or sed command all .11 gets changed. As an example:

inputip=10.135.10.11
newip=10.135.10.77

perl -i -e 's/$inputip/$newip/g' inputfile

OR

sed -e "s/$inputip/$newip/g" inputfile

The problem is all instance of .11 gets changed. so the above record of 10.135.10.111 is changed to 10.135.10.771, .772, .773, .77

Note: this line 10.135.10.11 A is not necessarily the last line, it's anywhere in the file.

markp-fuso
  • 28,790
  • 4
  • 16
  • 36
Aires69
  • 87
  • 6

2 Answers2

2

There are four problems with the Perl version.

  • You're missing -p.

  • You expected Perl to use the shell variables $inputip and $newip, but those are only found in the shell process. There's a number of ways to pass values to perl, as you can see in How can I process options using Perl in -n or -p mode?.

  • There's also a code injection bug, where . isn't matched literally.

  • There's an anchoring problem, where you accidentally modify IP addresses you don't want to change. For example, you will corrupt 210.135.10.11 when trying to change 10.135.10.11.

Fixed:

perl -i -spe's/\b\Q$o\E\b/$n/g' -- -o="$inputip" -n="$newip" inputfile
ikegami
  • 367,544
  • 15
  • 269
  • 518
1

Input:

$ cat inputfile
1.example.com,10.135.10.111,255.255.255.0,some comment
2.example.com,10.135.10.112,255.255.255.0,some comment
3.example.com,10.135.10.113,255.255.255.0,some comment
4.example.com,10.135.10.11,255.255.255.0, some comment
4.example.com,210.135.10.11,255.255.255.0, some comment
10.135.10.111 A
10.135.10.112 A
10.135.10.113 A
10.135.10.11  A
210.135.10.11 A

With GNU sed and word boundary sequences (\< / \>):

$ inputip=10.135.10.11
$ newip=10.135.10.77
$ sed "s/\<$inputip\>/$newip/g" inputfile
1.example.com,10.135.10.111,255.255.255.0,some comment
2.example.com,10.135.10.112,255.255.255.0,some comment
3.example.com,10.135.10.113,255.255.255.0,some comment
4.example.com,10.135.10.77,255.255.255.0, some comment
4.example.com,210.135.10.11,255.255.255.0, some comment
10.135.10.111 A
10.135.10.112 A
10.135.10.113 A
10.135.10.77  A
210.135.10.11 A

If this does not work then OP is likely not using GNU sed; in this case we'd need to know what version of sed is in use (eg, sed --version).

markp-fuso
  • 28,790
  • 4
  • 16
  • 36
  • Thank you Markp-fuso as well as Hatless for the quick response and answers. Both solution works!!! – Aires69 Aug 04 '22 at 19:33