免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 19033 | 回复: 12

[学习共享] bash 自带正则匹配功能 - BASH_REMATCH 介绍 [复制链接]

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
发表于 2014-02-15 19:18 |显示全部楼层
本帖最后由 rdcwayx 于 2014-03-05 11:59 编辑

从 bash 3以上版本里,已经自带正则匹配的功能, 很多情况下,可以不用awk/sed来做。 比如这个需求:

  1. <List>
  2.     <Job id="1" name="abc"/>
  3.     <Job id="2" name="zyz"/>
  4.     <Job id="3" name="beew"/>
  5. </List>
复制代码
想要得到这个结果。
  1. abc | 1
  2. zyz | 2
  3. beew | 3
复制代码
我们用纯shell的方法。
  1. #!/bin/bash

  2. while read  line; do
  3.   if [[ $line =~ id=\"([0-9]+).*name=\"([^\"]*) ]]; then
  4.     echo "${BASH_REMATCH[2]} | ${BASH_REMATCH[1]}"
  5.   fi
  6. done < file
复制代码
如果你对sed 里的 \1 \2 的用法很熟的话,就应该很快的明白 BASH_REMATCH[1] 和 BASH_REMATCH[2] 代表了什么。

把楼下@rogantianwz的回复帖在这里,解释的很不错。
  1.     双目运算符=~;它和==以及!=具有同样的优先级。如果使用了它,则其右边的字符串就被认为是一个扩展的正则表达式来匹配。如果字符串和模式匹配,则返回值是0,否则返回1。如果这个正则表达式有语法错误,则整个条件表达式的返回值是2。如果打开了shell的nocasematch 选项则匹配时不考虑字母的大小写。模式的任何部分都可以被引用以强制把其当作字符串来匹配。由正则表达式中括号里面的子模式匹配的字符串被保存在数组变量BASH_REMATCH 中。BASH_REMATCH 中下标为0的元素是字符串中与整个正则表达式匹配的部分。BASH_REMATCH 中下标为n的元素是字符串中与第n 个括号里面的子模式匹配的部分。
复制代码

论坛徽章:
13
双鱼座
日期:2013-10-23 09:30:05数据库技术版块每日发帖之星
日期:2016-04-20 06:20:00程序设计版块每日发帖之星
日期:2016-03-09 06:20:002015亚冠之塔什干火车头
日期:2015-11-02 10:07:452015亚冠之德黑兰石油
日期:2015-08-30 10:07:07数据库技术版块每日发帖之星
日期:2015-08-28 06:20:00数据库技术版块每日发帖之星
日期:2015-08-05 06:20:002015年迎新春徽章
日期:2015-03-04 09:57:09辰龙
日期:2014-12-03 14:45:52酉鸡
日期:2014-07-23 09:46:23亥猪
日期:2014-03-13 08:46:22金牛座
日期:2014-02-11 09:36:21
发表于 2014-02-16 09:38 |显示全部楼层
BASH_REMATCH用的不多,大多数人可能直接用sed了

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
发表于 2014-03-05 08:51 |显示全部楼层
回复 2# bikong0411

有的时候也很实用的。 比如下面这个帖子的七楼回复里,我就用了BASH_REMATCH, 你可以试着用sed去实现同样的功能,会觉得有些麻烦的。

http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4129647
   

论坛徽章:
2
水瓶座
日期:2014-02-28 14:20:09辰龙
日期:2014-06-16 13:18:51
发表于 2014-03-05 09:20 |显示全部楼层
恩,我觉得在用bash能解决问题的情况下还是用bash的好

论坛徽章:
0
发表于 2014-03-05 11:05 |显示全部楼层
回复 1# rdcwayx


    请问一下,id前面的~符号代表什么意思呀?

论坛徽章:
2
水瓶座
日期:2014-02-28 14:20:09辰龙
日期:2014-06-16 13:18:51
发表于 2014-03-05 11:43 |显示全部楼层
回复 5# hhdzhu


    双目运算符=~;它和==以及!=具有同样的优先级。如果使用了它,则其右边的字符串就被认为是一个扩展的正则表达式来匹配。如果字符串和模式匹配,则返回值是0,否则返回1。如果这个正则表达式有语法错误,则整个条件表达式的返回值是2。如果打开了shell的nocasematch 选项则匹配时不考虑字母的大小写。模式的任何部分都可以被引用以强制把其当作字符串来匹配。由正则表达式中括号里面的子模式匹配的字符串被保存在数组变量BASH REMATCH 中。BASH REMATCH 中下标为0的元素是字符串中与整个正则表达式匹配的部分。BASH REMATCH 中下标为n的元素是字符串中与第n 个括号里面的子模式匹配的部分。

评分

参与人数 1信誉积分 +5 收起 理由
guobaofu + 5 神马都是浮云

查看全部评分

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
发表于 2014-03-05 12:00 |显示全部楼层
rogantianwz 发表于 2014-03-05 11:43
回复 5# hhdzhu


这个解释的不错,把你的回复贴到我的首页里了,谢谢。

论坛徽章:
60
20周年集字徽章-20	
日期:2020-10-28 14:04:3015-16赛季CBA联赛之北京
日期:2016-07-06 15:42:0715-16赛季CBA联赛之同曦
日期:2016-06-12 10:38:0915-16赛季CBA联赛之佛山
日期:2016-05-27 11:54:56黄金圣斗士
日期:2015-12-02 11:44:35白银圣斗士
日期:2015-11-25 14:32:43白银圣斗士
日期:2015-11-23 12:53:352015亚冠之布里斯班狮吼
日期:2015-10-21 16:55:482015亚冠之首尔
日期:2015-09-01 16:46:052015亚冠之德黑兰石油
日期:2015-08-31 11:39:192015亚冠之萨济拖拉机
日期:2015-08-28 21:06:5315-16赛季CBA联赛之广东
日期:2016-07-12 14:58:53
发表于 2014-03-05 12:36 |显示全部楼层
学习了! 善于发现善于学习的各位大佬 , 想不到还有很多的内置变量数组.

论坛徽章:
0
发表于 2014-03-05 22:11 |显示全部楼层
回复 6# rogantianwz


    谢谢!但是这句我还是看不懂:if [[ $line =~ id=\"([0-9]+).*name=\"([^\"]*) ]];这句话的意思 匹配id="一个多个数字然后匹配任意字符匹配name="除"的其他字符任意字符.这里默认每个标签的格式都是正确的是吧,name后面格式不对也会匹配啊。如果=~ 前后匹配就返回0的话if不就为假了吗,不就不会交换了吗?还有^符号只有不再[]里面才表示行首的意思吗?谢谢了,不甚感激啊

论坛徽章:
2
水瓶座
日期:2014-02-28 14:20:09辰龙
日期:2014-06-16 13:18:51
发表于 2014-03-06 00:01 |显示全部楼层
回复 9# hhdzhu


    1.
name后面格式不对也会匹配啊
没看懂,只要name"后边还有另外一个"就能匹配上
    2.
如果=~ 前后匹配就返回0的话if不就为假了吗
返回0的话if为真
    3.
还有^符号只有不再[]里面才表示行首的意思吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP