How to search for all sentences in the text and replace them with another sentence (search and validate the IPv4 address)

advertisements

How to make search for all phrases in the text and replace them with another phrase

(by using sed and/or awk and/or grep and/or perl) ?

It's about replacing one IPv4 address with another one and verify that the value found is the correct IPv4 address.

Here's an example:

ip_node:<ip_address> e.g. ip_node:192.168.0.1

These should be replaced by

ip_address:<ip_address>” e.g. "ip_address:192.168.0.1"


Additional assumptions:

-> Phrases such
   192.168.000.001, 072.12.01.1, 256.224.1.010, 20.128.300.01
   and similar aren't propoer IPv4 addresses and should be marked as
   invalid IPv4 address and possibly write to another file.
-> Phrases containing less/more than 4 octets aren't also considered
   to be a valid IPv4 addresses and like above should be marked as
   invalid IPv4 address and possibly write to another file.
-> Phrases containing any character other than a digit [0..9] aren't also
   considered to be a valid IPv4 addresses and like above should be marked as
   invalid IPv4 address and possibly write to another file.


Content of sample file:

ip_node:192.168.0.1
ip_node:192.268.0.01
ip_node:10.0.0.0
ip_node:10.0.0000.10
ip_node:10.255.255.255
ip_node:10.255.255.255.12
ip_node:172.16.0.0
ip_node:172.16.0
ip_node:172.31.255.255
ip_node:172.31.255.
ip_node:0.0.0.0
ip_node:01.0.01.0
ip_node:255.255.255.255
ip_node:255.259.255.259
ip_node:224.0.0.0
ip_node:224.0.
ip_node:207.142.131.236
ip_node:207.002.001.06
ip_node:255.255.255.0
ip_node:055.2255.1255.0
ip_node:204.144.134.234
ip_node:2o7.0o2.0E.O6
ip_node:245.245.245.40
ip_node:O55.2255.1255.a0

Content of output file1-all (with all entries):

ip_address:192.168.0.1
[!]ip_node:192.268.0.01  -- [invalid IP address]
ip_address:10.0.0.0
[!]ip_node:10.0.0000.10  -- [invalid IP address]
ip_address:10.255.255.255
[!]ip_node:10.255.255.255.12  -- [invalid IP address]
ip_address:172.16.0.0
[!]ip_node:172.16.0  -- [invalid IP address]
ip_address:172.31.255.255
[!]ip_node:172.31.255.  -- [invalid IP address]
ip_address:0.0.0.0
[!]ip_node:01.0.01.0  -- [invalid IP address]
ip_address:255.255.255.255
[!]ip_node:255.259.255.259  -- [invalid IP address]
ip_address:224.0.0.0
[!]ip_node:224.0.  -- [invalid IP address]
ip_address:207.142.131.236
[!]ip_node:207.002.001.06  -- [invalid IP address]
ip_address:255.255.255.0
[!]ip_node:055.2255.1255.0  -- [invalid IP address]
ip_address:204.144.134.234
[!]ip_node:2o7.0o2.0E.O6  -- [invalid IP address]
ip_address:245.245.245.40
[!]ip_node:O55.2255.1255.a0  -- [invalid IP address]

Content of output file2-bad (only with bad entries):

[!]ip_node:192.268.0.01  -- [invalid IP address]
[!]ip_node:10.0.0000.10  -- [invalid IP address]
[!]ip_node:10.255.255.255.12  -- [invalid IP address]
[!]ip_node:172.16.0  -- [invalid IP address]
[!]ip_node:172.31.255.  -- [invalid IP address]
[!]ip_node:01.0.01.0  -- [invalid IP address]
[!]ip_node:255.259.255.259  -- [invalid IP address]
[!]ip_node:224.0.  -- [invalid IP address]
[!]ip_node:207.002.001.06  -- [invalid IP address]
[!]ip_node:055.2255.1255.0  -- [invalid IP address]
[!]ip_node:2o7.0o2.0E.O6  -- [invalid IP address]
[!]ip_node:O55.2255.1255.a0  -- [invalid IP address]

Content of output file3-good (only with valid entries):

ip_address:192.168.0.1
ip_address:10.0.0.0
ip_address:10.255.255.255
ip_address:172.16.0.0
ip_address:172.31.255.255
ip_address:0.0.0.0
ip_address:255.255.255.255
ip_address:224.0.0.0
ip_address:207.142.131.236
ip_address:255.255.255.0
ip_address:204.144.134.234
ip_address:245.245.245.40

Attempts:

sed -i -e "s/ip_node:/ip_address:/g" <file>

and this:

sed -i -e "s/ip_node:^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][‌​0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/ip_address:^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0‌​-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/g" <file>


What's wrong with "01.0.01.0" or "207.002.001.06"? Why do you think they are invalid?

perl -MRegexp::Common -nle '
    if (/ip_node:\K(\S+)/ && $1 =~ /^($RE{net}{IPv4})$/) {
        print "ip_address", $1;
    } else {
        print "[!]", $_;
    }
' filename

outputs

ip_address192.168.0.1
[!]ip_node:192.268.0.01
ip_address10.0.0.0
[!]ip_node:10.0.0000.10
ip_address10.255.255.255
[!]ip_node:10.255.255.255.12
ip_address172.16.0.0
[!]ip_node:172.16.0
ip_address172.31.255.255
[!]ip_node:172.31.255.
ip_address0.0.0.0
ip_address01.0.01.0
ip_address255.255.255.255
[!]ip_node:255.259.255.259
ip_address224.0.0.0
[!]ip_node:224.0.
ip_address207.142.131.236
ip_address207.002.001.06
ip_address255.255.255.0
[!]ip_node:055.2255.1255.0
ip_address204.144.134.234
[!]ip_node:2o7.0o2.0E.O6
ip_address245.245.245.40
[!]ip_node:O55.2255.1255.a0

For splitting it into your desired output files, I would:

perl -MRegexp::Common -nle '... as above ...' filename |
tee file1-all |
awk '/^\[!\]/ {print > "file2-bad"; next} {print > "file3-good"}'