Sed 中正则表达式一个小坑
要把一个监控任务自动化。
监控任务如下:
通过网页查看商品库存数量。如果库存小于阀值,就通知进行补货。
获取网页内容保存本地后。是用下面的脚本获取库存数量
1 | cnt=`grep "库存: " html.txt | sed "s/^.*([0-9]+).*$/\1/g"` |
商品库存在网页中的格式如下:
1 | <b>库存数: 1105</b> <br/> |
结果测试时,打印cnt的值,一直显示为:5
开始百思不得解。
正则表达式没有错啊。
把括号中的部分改为: ([0-9]{4})
这次cnt的值对了:是1105
考虑到库存可能因为销售太快,小于1000,那个就会获取不到。把括号部分改为: ([0-9]{1,4})
重新测试后,发现cnt的值又变为5了。
这下明白了,问题不在括号部分。而在括号的前面的内容。
sed的正则表达式是贪婪匹配模式的。就是说,一个正则模式会尽可能的匹配最大长度。
这里表达式的第一个变长匹配模式为:.因为数字也能匹配”.”, 所以“.”模式不会在第一个数字前停止。会持续匹配,直到后面的内容不能满足匹配,才回退。
所以针对这个例子,我们把sed的正则替换模式修改为:
1 | ^.*: ([0-9]+).*$ |
这样,第一个匹配模式在遇到”: “结束。
这样在“: ”后面,”([0-9]+)”模式开始贪婪匹配,匹配出来最长的连续数字,从而获取出正确的库存数。
修改后测试cnt的值为:1105
最后附上自动脚本相关部分的代码
1 | minute=`date "+%"` |