2014-07-09 32 views
0

请帮我理解下面的语法:bash脚本 - 无法验证IP

#!/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 

随着输入923.234214.23,结果是valid。 与923.3444.2123,它是invalid

我该如何解决这个问题?

+2

也许你只是想“\”。 - 意思是点而不是“。” - 意思是任何角色? – cerkiewny

+1

'[。]'不''(反斜杠转义有时也可以,但是在多层解析中更容易丢失)。 –

回答

3

我认为你正在使用.代替\.

下面的脚本应该做你想要什么:

#!/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 

如果你想在实际检查给出你可以看看这些数字的范围更先进的脚本进入这个linux journal article

+0

嗨, 你的脚本和我的区别是什么? 没有得到任何区别.. – Ajain

+0

哦,我以为你用点不是斜杠点,但现在我很困惑,因为如果没有什么区别,我不知道为什么我getyting:./test 输入你的价值923.234214.23 无效 – cerkiewny

+1

哦,现在好了,我明白了,编辑你的问题的人不小心修复了你的问题。无论如何,你需要使用“\”。在那些“[0-9] {1,3}”之间“而非简单地”。“ – cerkiewny

2

这比一个真正的答案注释,但...

# _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 

由于这已经说明,关键的一点是采用了反斜线\)的。单独的.)将匹配任何单个字符。 [0-9]{1,3}部分的含义是“匹配1到3位的任何序列”。

因此,从广义上讲,正则表达式将匹配具有1至3通过分离任何字符位数4个序列的任意字符串:

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 

这可能是在第一个令人吃惊,但是它匹配。 ..


作为一个侧面说明,即使是“反斜线点正则表达式”将接受非有效的IPv4地址:例如923.34.42.123将匹配,但显然是不正确。为了好玩,这里有一个基于awk的过滤器(及其测试集),用于从列表中删除无效的IPv4地址。随意适应您的需求(或完全忽略它;)

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 

这里是结果:

4.2.2.2 
192.168.1.1 
0.0.0.0 
255.255.255.255 
192.168.0.1 
3

而对于一个真正的答案,现在,如果你想检查IPv4地址使用只有bash,你必须使用稍微复杂一点的正则表达式。我使用一个中间变量这里保留的东西可以理解的:答复

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 
0

谢谢我终于找到了解决办法

if [[ $ip =~ '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' ]] 

我没有使用单引号。