今天在写一个 bash 脚本时, 有一部分需要判断 ip 的格式.
这样的功能自然就想到了高大上的正则表达式同学.

但记得 bash 并不直接支持正则表达式. 于是用 sed 实现了这个功能.

不过, 因为好奇大牛们是怎么处理类似问题的, 仍然去搜索了一下.

发现原来 bash 也支持正则表达式(误).
大概说法是这样的. 在 [[ ]] 中写正则就可以了. 下面是一个例子

if [[ 1 =~ [0-9] ]];then echo 0;fi

于是用这种方式, 完成了最初那个 ip 格式判断的需求…

好吧, 我承认是直接抄这里的: BASH脚本中使用正则表达式检查IP地址和端口号

PS. 测试过 255.255.255.256 这样的 ip 是不通过的 : )

思考

一般来说, 需求完成了. 我们就可以收工了.
但本着逗[哔]的探究精神, 对 [[ ]] 做了如下测试

if [[ 1 = [0-9] ]]];then echo 0;fi

结果输出: 0.

哇嚓, 所以 = 就可以了吗? 那 =~ 是用来干嘛的???

正则的话, 除了 match 还有 search 方式.
Ok, 测试下:

if [[ abc123ddd = [0-9] ]];then echo 0;fi
if [[ abc123ddd =~ [0-9] ]];then echo 0;fi

第一行无输出, 第二行输出: 0.

明了: = 是完全匹配, 即 match; =~ 部分匹配, 即 search

好了, 再来试一下其它元字符

if [[ 12 = [0-9]. ]];then echo 0;fi

没结果输出

哇嚓, 这又是怎么回事…

if [[ 12 = [0-9]* ]];then echo 0;fi

输出: 0.

难道…

if [[ 12 = ?? ]];then echo 0;fi
if [[ 12 = * ]];then echo 0;fi

以上两行均有输出.

原来如此, [[ ]] 并不支持正则表达式. 它所支持的是 glob 表达式, 也就是我们常说的 通配符

总结

探索结束. 总结一下

  1. [[ expression ]] 并不支持正则表达式, 其支持的是 glob 表达式
  2. [[ ]] 中可以用 = 表达匹配, 要示左侧字符串和右侧 glob 完全匹配
  3. 也可以使用 =~ 进行搜索, 只要左侧字符串有部分与右侧匹配即可

  Linux
  bash, glob, 正则