Hydrosine
Hydrosine

Reputation: 145

Regex for converting 001002003004.test.com to an IP

For a special scenario I've set up an domain address which can be transformed to an (internal) IP address.

001002003004.test.com should revert to 1.2.3.4 as IP.

I've come to the following SED lines but i have the feeling it is very bulky and could be done much easier! For one case it does not work, although it is unlikely for this scenario to exist i would like to have it working.

My data:

user@linuxmachine:/home/user# cat regex.test 
010005248210.test.com
172017170003.test.com
172000017003.test.com
001002003004.test.com
000000000001.test.com
091021000103.test.com
192168123254.test.com
172000000010.test.com

My transformation line:

cat regex.test | sed -r 's/([0-9]{3})/\1\./g' | sed -r "s/^0*//" | sed -r "s/\.0*/\./g" | sed -r "s/\.\.test.com//" | sed -r "s/\.\./\.0\./g" 

output:

10.5.248.210
172.17.170.3
172.0.17.3
1.2.3.4
.0..1
91.21.0.103
192.168.123.254
172.0..10

The 000000000001.test.com doesn't need to work as this is an impossible IP. but the 172000000010.test.com I need working.

I was thinking that the g flag on the final SED would replace all occurences.. but it doesn't seem so. what can i do to improve this?

Upvotes: 2

Views: 103

Answers (7)

Avinash Raj
Avinash Raj

Reputation: 174706

Even more simpler sed commands,

sed -r 's/^([0-9]{3})([0-9]{3})([0-9]{3})([0-9]{3}).*$/\1.\2.\3.\4/g; s/(^|\.)0*([0-9]+)/\1\2/g' file

Example:

$ sed -r 's/^([0-9]{3})([0-9]{3})([0-9]{3})([0-9]{3}).*$/\1.\2.\3.\4/g; s/(^|\.)0*([0-9]+)/\1\2/g' rr
10.5.248.210
172.17.170.3
172.0.17.3
1.2.3.4
0.0.0.1
91.21.0.103
192.168.123.254
172.0.0.10

OR

sed -r 's/^([0-9]{3})([0-9]{3})([0-9]{3})([0-9]{3}).*$/\1.\2.\3.\4/g; s/0+([0-9]+\.?)/\1/g' file

Example:

$ sed -r 's/^([0-9]{3})([0-9]{3})([0-9]{3})([0-9]{3}).*$/\1.\2.\3.\4/g; s/0+([0-9]+\.?)/\1/g' file
10.5.248.210
172.17.170.3
172.0.17.3
1.2.3.4
0.0.0.1
91.21.0.13
192.168.123.254
172.0.0.10

Upvotes: 1

NeronLeVelu
NeronLeVelu

Reputation: 10039

By step, removing the line (empty) starting with 0 as IP and leading 0 from each number

sed -e 's/\..*//;s/\(...\)/.\1/g;s/\.0\{0,2\}/./g;s/.\(0.*\)*//' regex.test 

10.5.248.210
172.17.170.3
172.0.17.3
1.2.3.4

91.21.0.103
192.168.123.254

Upvotes: 1

Thor
Thor

Reputation: 47099

Here is another GNU sed alternative:

<regex.test sed -r 's/\..*//; s/.{3}/&./g; s/(^|\.)0{1,2}/\1/g; s/\.$//'

If you allow the use of cut:

<regex.test cut -d. -f1 | sed -r 's/.{3}/&./g; s/(^|\.)0{1,2}/\1/g; s/\.$//'

cut from GNU coreutils can also be used to separate the groups:

<regex.test cut --output-delimiter=. -c1-3,4-6,7-9,10-12 | sed -r 's/(^|\.)0{1,2}/\1/g'

Output in all cases:

10.5.248.210
172.17.170.3
172.0.17.3
1.2.3.4
0.0.0.1
91.21.0.103
192.168.123.254
172.0.0.10

Upvotes: 1

Jotne
Jotne

Reputation: 41456

Here is another more simple approach with awk

awk '{for (i=1;i<11;i+=3) printf substr($0,i,3)+0(i==10?RS:".")}' file
10.5.248.210
172.17.170.3
172.0.17.3
1.2.3.4
0.0.0.1
91.21.0.103
192.168.123.254
172.0.0.10

Upvotes: 2

Kent
Kent

Reputation: 195079

I would do with gawk (>=4.0) 's FPAT :

test with your file:

kent$  awk -v FPAT='.{3}' '{printf "%d.%d.%d.%d\n",$1+0,$2+0,$3+0,$4+0}' file  
10.5.248.210
172.17.170.3
172.0.17.3
1.2.3.4
0.0.0.1
91.21.0.103
192.168.123.254
172.0.0.10

Upvotes: 4

Idriss Neumann
Idriss Neumann

Reputation: 3838

First, no need to use cat and no need to use multiple sed. You could use :

sed -r 's/([0-9]{3})/\1\./g;s/^0*//;s/\.0*/\./g;s/\.\.test.com//;s/\.\./\.0\./g' regex.test

Instead of :

cat regex.test | sed -r 's/([0-9]{3})/\1\./g' | sed -r "s/^0*//" | sed -r "s/\.0*/\./g" | sed -r "s/\.\.test.com//" | sed -r "s/\.\./\.0\./g"

You'll get the same result (which is not yet correct).

Then, here is a solution that works with a single sed :

$ sed -r 's/([0-9]{3})/\1\./g;s/\.\.test.com//;s/0+([0-9]+\.?)/\1/g' regex.test
10.5.248.210
172.17.170.3
172.0.17.3
1.2.3.4
0.0.0.1
91.21.0.13
192.168.123.254
172.0.0.10

Upvotes: 1

cadrian
cadrian

Reputation: 7376

Same as Idriss but shorter:

sed -r 's/([0-9]{3})/\1\./g;s/(^|\.)0*([0-9]+)/\1\2/g;s/\.\.test.com//' regex.test

Upvotes: 2

Related Questions