Thursday, February 17, 2022

[SOLVED] Grep IP Address within Class B networks only

Issue

172.16.0.0/12 is a Class B networks. I would like to grep IP from this Class only.

Here is the sample log file.

[user@linux ~]$ cat ClassB.txt
172.16.0.0/12 is a Class B networks
172.16.0.0 – 172.31.255.255
Network:    172.16.0.0/12
HostMin:        172.16.0.1
HostMax:        172.31.255.254
Broadcast:      172.31.255.255
Out of range:   172.32.255.254
Out of range:   172.15.0.1
Out of range:   172.4.0.1
[user@linux ~]$

If I use egrep -n '172.[1-3][0-9]' ClassB.txt, this will grep 172.32.255.254 as well which is out of Class B range.

[user@linux ~]$ egrep -n '172.[1-3][0-9]' ClassB.txt
1:172.16.0.0/12 is a Class B networks
2:172.16.0.0 – 172.31.255.255
3:Network:              172.16.0.0/12
4:HostMin:              172.16.0.1
5:HostMax:              172.31.255.254
6:Broadcast:            172.31.255.255
7:Class B:              172.19.0.1
8:Class B:              172.20.0.1
9:Out of range:         172.32.255.254
10:Out of range:        172.15.0.1
[user@linux ~]$

What should I do to grep only Class B IP Address only which is from 172.16.0.0 to 172.31.255.255

Desired Output

[user@linux ~]$ <grep/egrep command here> ClassB.txt
1:172.16.0.0/12 is a Class B networks
2:172.16.0.0 – 172.31.255.255
3:Network:              172.16.0.0/12
4:HostMin:              172.16.0.1
5:HostMax:              172.31.255.254
6:Broadcast:            172.31.255.255
7:Class B:              172.19.0.1
8:Class B:              172.20.0.1
[user@linux ~]$

Solution

what i would do is this

grep "172\.\(1[6-9]\|2[0-9]\|3[01]\)\.[0-9]\{1,3\}\.[0-9]\{1,3\}" ClassB.txt

but getting the answer is not getting a solution, so let me explain. Using double quotes or single is a form of choice, and the nuance is in the escaping. I tend to use double, but the single form is exactly the same in this example.

grep  '172\.\(1[6-9]\|2[0-9]\|3[01]\)\.[0-9]\{1,3\}\.[0-9]\{1,3\}' ClassB.txt

This regex assumes the input is validated, ie you dont have an ip address that is out of bounds. like say 172.31.555.1. This simplifies it from the validating grep expression

grep  "172\.\(1[6-9]\|2[0-9]\|3[01]\)\.\([0-9]\.\|[1]\{,1\}[0-9]\{2\}\.\|2[0-4][0-9]\.\|25[0-5]\.\)\([0-9]\|[1]\{,1\}[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)" ClassB.txt

edit: I forgot my explanation

the validating answer has 3 subgroups

\(1[6-9]\|2[0-9]\|3[01]\)\.
\([0-9]\.\|[1]\{,1\}[0-9]\{2\}\.\|2[0-4][0-9]\.\|25[0-5]\.\)
\([0-9]\|[1]\{,1\}[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)

and they relate to the three ending parts of the ip address, you could replace the second with the third and follow it with a \. and it would technically be the same, as there are often many regex that work but look totally different. I normally choose the first one that is simpler, because most input is validated, if it isnt it requires validation regex.

If for instance you just wanted all ip addresses a much simpler regex would be

grep "\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}" ClassB.txt

again this would require that the input be prevalidated.



Answered By - Chris
Answer Checked By - Pedro (WPSolving Volunteer)