With the following grep syntax I want to match all IP address in a file (from a ksh script)
grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' fileThe problem: It also matches words (IP) that have more then 4 octets:
1.1.1.1.1 or
192.1.1.1.160How can I match a valid IP and only IP addresses with 4 octets? I can also use Perl – a one line syntax solution, if grep doesn't work.
13 Answers
try this:
grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/hostswhich matches all expressions from 0.0.0.0 to 999.999.999.999
with
grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/hostsyou will get IP addresses only
note:
on solaris probably egrep will do the job.
How's this:
perl -MRegexp::Common=net -ne '/($RE{net}{IPv4})/ and print "$1\n"' /etc/hosts 2 The
-w / --word-regexp flag to grep makes it only match on word boundaries, meaning that your match must either be surrounded by whitespace or begin / end at the beginning / end of the line!
To only find matches with 4 octets exactly (excluding things like 1.1.1.1.1) use this:
grep -P '(?<=[^0-9.]|^)[1-9][0-9]{0,2}(\.([0-9]{0,3})){3}(?=[^0-9.]|$)'It should never detect non-IP-addresses. The expression could be more complex to verify more things but this should work for most cases. It will not match a preceding 0 since 010.1.12.1 is not a common way to write IP addresses.
if [ ` echo $ip | '^((25[0-5]|2[0-4][0-9]|[01]?[1-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[1-9][0-9]?)$' | grep -o "\." | wc -l` -eq 1 ];
then ipv4=true;
else
ipv4=false; A little tricky, but it should work:
( X='\([0-9]\{1,2\}\|1[0-9]\{2\}\|2[0-4][0-9]\|25[0-5]\)' ; grep "\([^\.]\|^\)$X\.$X\.$X\.$X\([^\.]\|$\)" file ) 4 A shorter version of the long regex:
egrep '([1-2]?[0-9]{0,2}\.){3,3}[1-2]?[0-9]{0,2}' Please use grep -E or egrep as suitable to your OS version
2grep -E '^((25[0-5]|2[0-4][0-9]|[1]?[1-9][0-9]?).){3}(25[0-5]|2[0-4][0-9]|[1]?[1-9]?[0-9])$'
Modified version of Arnaud B.'s answer.
This expression will not match IP addresses with leading 0s. e.g., it won't match 192.168.1.01 This expression will not match IP addresses with more than 4 octets. e.g., it won't match 192.168.1.2.3
1I'm using egrep "^([0-9]{1,3}\.){3}[0-9]{1,3}" /etc/hosts to match IP adresses at the beginning of a line.
It can also be used without the ^ to allow white spaces or other chars before the IP address.
[0-9]{1,3} --> this matches a number between 1 and 999.
\. --> this is to add the dot.
([0-9]{1,3}\.){3} --> get a number with a dot 3 times.
[0-9]{1,3} --> finally add the fourth number. grep -Eo '([0-9]{1,3}.?){4}'
Example : curl | grep "IP visible depuis mon serveur" | grep -Eo '([0-9]{1,3}.?){4}'
Regular expression for matching an ip address in TCL
set a "192.168.10.25"
if {[regexp {^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$} $a]} { puts "yes" }
Old chain, but I needed a grep which would ALSO CATCH CIDR masks (8-32), so I use this:
grep -Eo "\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]\
|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\
([/]([8-9]|[12][0-9]|3[0-2]))?\b"The above can be improved ;)
Now if mask is other than 8-32 but if the "IP-part" is still valid, grep returns the "IP-part".
Here is what worked for me for ksh and ksh93 in AIX:
ip=
[[ $ip == [0-9]@(""|[0-9])@(""|[0-9]).[0-9]@(""|[0-9])@(""|[0-9]).[0-9]@(""|[0-9])@(""|[0-9]).[0-9]@(""|[0-9])@(""|[0-9]) ]] && echo OK || echo NOK The above can be modified in order to "filter" the provided IP to whatever pattern is desired.