Reputation: 31
Please help me to understand the syntax below:
#!/bin/bash
read -p "enter your value" ip
if [[ $ip =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]
then
echo "valid"
else
echo "invalid"
fi
With input 923.234214.23
, the result is valid
.
With 923.3444.2123
, it is invalid
.
How can I solve this?
Upvotes: 0
Views: 339
Reputation: 31
Thanks for reply finally i found a solution
if [[ $ip =~ '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' ]]
i was not using single quote.
Upvotes: 0
Reputation: 2851
I think you are using .
instead of \.
the following script should do what you want:
#!/bin/bash
read -p "enter your value" ip
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
then
echo "valid"
else
echo "invalid"
fi
If you want more advanced script actually checking the scope of the numbers given you could look into this linux journal article.
Upvotes: 3
Reputation: 52000
And for a real answer now, if you want to check for IPv4 addresses using only bash, you have to use a slightly more complex regex. I use an intermediate variable here to keep the things understandable:
BYTE='((0*1?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))'
# ^^^^^^^^^^^^^^^^^ matches 0-199 (with optional leading zeros
# ^^^^^^^^^^^^^ matches 200-249
# ^^^^^^^^^ matches 250-255
if [[ $ip =~ ^$BYTE\.$BYTE\.$BYTE\.$BYTE$ ]]
then
# ...
else
# ...
fi
Upvotes: 3
Reputation: 52000
This is more a comment than a real answer but...
# _your_ regex:
sh$ [[ 923.34442.123 =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]] && echo ok || echo notok
ok
# regex using backslash:
sh$ [[ 23.34442.123 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] && echo ok || echo notok
notok
As this has already been explained, the key point is the use of the backslash (\
). The dot (.
) alone will match any single character. The [0-9]{1,3}
part means "match any sequence of 1 to 3 digit".
So, broadly speaking, your regex would match any string having 4 sequences of 1 to 3 digits separated by any char:
9 2 3 . 3 4 4 4 2 . 1 2 3
d d d a d d d a d a d d d
i i i n i i i n i n i i i
g g g y g g g y g y g g g
i i i c i i i c i c i i i
t t t h t t t h t h t t t
a a a
r r r
It might be surprising at first, but it matches...
As a side note, even the "backslash-dot regex" will accept non valid IPv4 addresses: for example 923.34.42.123
would match, but is obviously incorrect. So for fun here is an awk
based filter (and its test set) to remove invalid IPv4 addresses from a listing. Feel free to adapt to your needs (or ignore it completely;)
sh$ BYTE='[0-2]?[0-9]?[0-9]' # Might even be BYTE='0*[0-2]?[0-9]?[0-9]'
sh$ cat << EOF | awk -v FS='.' "/^$BYTE\.$BYTE\.$BYTE\.$BYTE$/"' {
if (($1<= 255)&&($2<=255)&&($3<=255)&&($4<=255))
print $0 }'
4.2.2.2
a.b.c.d
192.168.1.1
0.0.0.0
255.255.255.255
255.255.255.256
192.168.0.1
192.168.0
1234.123.123.123
EOF
And here is the result:
4.2.2.2
192.168.1.1
0.0.0.0
255.255.255.255
192.168.0.1
Upvotes: 1