0

The target of the following perl one liner code is to replace the first three octets ( in case the four octet is digit/number - xxx.xxx.xxx.digit )

  • remark - I use linux and solaris machines

The problem is that the perl one liner will also replace the first three octets while the four octet IP is not valid IP octet ( for example 5.5.5.555 )

The following perl one liner code example show how the perl syntax replaced the first three octets in spite the four octet isn’t VALID IP

# export OLD_IP=1.1.1
# export NEW_IP=5.5.5
# echo 1.1.1.555 | perl -i -pe 'next if /^ *#/; s/(?<![\d.])\Q$ENV{OLD_IP}\E(?=\.\d)/$ENV{NEW_IP}/g'
5.5.5.555

Please advice what need to add in my perl one liner code , in order to replace the first three octets

only if four octet is VALID IP ( between 0 – 255 )

  • How is this not answered by your last question? – ikegami Mar 01 '13 at 11:22
  • ikagami - its not the same quastion , in this case I ask about how to edit file , not as the previos quastion that talk about how to match , the previos quastion cant help me to edit files ! –  Mar 01 '13 at 11:36
  • @Ikegami please tell me how I can edit files ( replace IP ) using the previos quastion - grep + match exactly IP address with Regular Expression ???????? –  Mar 01 '13 at 11:45

3 Answers3

0

If the final octet is always just a single digit then you can do the same as at the start of the pattern and ensure that there is no digit after the first.

s/(?<![\d.])\Q$ENV{OLD_IP}\E(?=\.\d(?!\d))/$ENV{NEW_IP}/g

This way is much easier than checking for a valid final octet from 0 to 255, which would look like

s/(?<![\d.])\Q$ENV{OLD_IP}\E(?=\.(?:1?\d?\d|2[0-4][0-9]|25[0-5])(?!\d))/$ENV{NEW_IP}/g
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • the target is to check the VALID of the last octet - so we must to verify the last octet between 0 to 255 , –  Mar 01 '13 at 10:45
  • Then why do you say *"in case the four octet is digit/number - xxx.xxx.xxx.digit"* – Borodin Mar 01 '13 at 10:49
0

My first thought is to use a regular expression:

Next expresion should get you started, it checks for different groups, single digits 0 to 9, double digits 0 to 9, three digits starting with 1, three digits starting with 2 but not followed by 5, three digits followed by 5 restricted to 5 for the third digit

^(?:[23456789]|[0123456789][0123456789]|1[0123456789][0123456789]|2[01234][0123456789]|25[012345]?)$

did test it in an online regex tester and it seems to filter it nicely

my knowledge of PERL has been dorment for over twelve years, but shouldn't it be possible to get the output and check that for value:

/\d\.\d\.\d\.(\d)/ if $1 < 255
Daan
  • 31
  • 3
0

Here is a simple solution using the eval flag for substitution:

perl -i -pe 's/\b(1\.1\.1\.(\d+))\b/ $2 >= 0 && $2 < 255 ? "5.5.5.$2" : $1/ge'

Test:

echo 1.1.1.12 | perl -i -pe 's/\b(1\.1\.1\.(\d+))\b/ $2 >= 0 && $2 < 255 ? "5.5.5.$2" : $1/ge'
5.5.5.12

echo 1.2.1.256 | perl -i -pe 's/\b(1\.1\.1\.(\d+))\b/ $2 >= 0 && $2 <= 255 ? "5.5.5.$2" : $1/ge'
1.2.1.256
rjh
  • 49,276
  • 4
  • 56
  • 63