user1121951
user1121951

Reputation:

grep + match exactly IP address with Regular Expression

my target is to match exactly IP address with three octes , while the four IP octet must be valid octet - between <0 to 255>

For example I have the following IP's in file

$ more file    
192.9.200.10
192.9.200.100
192.9.200.1555
192.9.200.1
192.9.200.aaa
192.9.200.@
192.9.200.:
192.9.200
192.9.200.

I need to match the first three octets - 192.9.200 while four octet must be valid ( 0-255)

so finally - expects result should be:

192.9.200.10
192.9.200.100
192.9.200.1

the basic syntax should be as the following:

IP_ADDRESS_THREE_OCTETS=192.9.200
cat file | grep -x $IP_ADDRESS_THREE_OCTETS.[  grep‏ Regular Expression syntax ]

Please advice how to write the right "grep regular Expression" in the four octets in order to match the three octets , while the four octets must be valid?

Upvotes: 1

Views: 5673

Answers (4)

Thomas
Thomas

Reputation: 21

grep -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])$'

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

Upvotes: 2

fenway
fenway

Reputation: 446

If you really want to be certain that what you have is a valid IPv4 address, you can always check the return value of inet_aton() (part of the Socket core module).

Upvotes: 0

ikegami
ikegami

Reputation: 385506

You'd need to use some high-level tools to convert the text to a regex pattern, so you might as well use just that.

perl -ne'
    BEGIN { $base = shift(@ARGV); }
    print if /^\Q$base\E\.([0-9]+)$/ && 0 <= $1 && $1 <= 255;
' "$IP_ADDRESS_THREE_OCTETS" file

If hardcoding the base is acceptable, that reduces to:

perl -ne'print if /^192\.9\.200\.([0-9]+)$/ && 0 <= $1 && $1 <= 255' file

Both of these snippets also accept input from STDIN.


For a full IP address:

perl -ne'
    BEGIN { $ip = shift(@ARGV); }
    print if /^\Q$ip\E$/;
' 1.2.3.4 file

or

perl -nle'
    BEGIN { $ip = shift(@ARGV); }
    print if $_ eq $ip;
' 1.2.3.4 file

Upvotes: 3

Chris Seymour
Chris Seymour

Reputation: 85775

Regexp is not good for comparing numbers, I'd do this with awk:

$ awk -F. '$1==192 && $2==9 && $3==200 && $4>=0 && $4<=255 && NF==4' file
192.9.200.10
192.9.200.100
192.9.200.1

If you really want to use grep you need the -E flag for extended regexp or use egrep because you need alternation:

$ grep -Ex '192\.9\.200\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])' file
192.9.200.10
192.9.200.100
192.9.200.1

$ IP=192\.9\.200\.

$ grep -Ex "$IP(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])" file

Note: You must escaped . to mean a literal period.

Upvotes: 2

Related Questions