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)