免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: winteryxu
打印 上一主题 下一主题

[文本处理] 关于grep匹配的问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2014-05-18 18:20 |只看该作者
回复 9# winteryxu

还是有个疑问。您所说的grep '(*[1-9])'   相当于 grep '([1-9])' 或  grep '[1-9])'
为什么会相当于grep '[1-9])'呢?


如我5楼所述,*表示之前的结构出现任意次,包含0次。
所以(*[1-9])相当于([1-9])或(([1-9])或((([1-9])或((...([1-9),这里的(可以出现任意次数,当它出现0次时,即为[1-9])。

论坛徽章:
0
12 [报告]
发表于 2014-05-18 18:28 |只看该作者
回复 10# winteryxu

这个不太了解,我一般是使用Perl正则,grep -P。

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
13 [报告]
发表于 2014-05-19 10:21 |只看该作者
回复 1# winteryxu

楼主比较一下:
  1. [seesea@UC ~]$ echo "LAYER AL_RDL ..... TOTAL Original Geometry Count = 8447    (10013)" | grep '([1-9]*)'
  2. [seesea@UC ~]$ echo "LAYER AL_RDL ..... TOTAL Original Geometry Count = 8447    (10013)" | grep -E '([1-9]*)'
  3. LAYER AL_RDL ..... TOTAL Original Geometry Count = 8447    (10013)
  4. [seesea@UC ~]$ echo "LAYER AL_RDL ..... TOTAL Original Geometry Count = 8447    (10013)" | egrep '([1-9]*)'  
  5. LAYER AL_RDL ..... TOTAL Original Geometry Count = 8447    (10013)
复制代码

论坛徽章:
0
14 [报告]
发表于 2014-05-19 12:05 |只看该作者
感谢楼上几位朋友,这个问题,我想我是弄明白了,下面是我的理解。
文档中都是这种:
LAYER AL_RDL ..... TOTAL Original Geometry Count = 8447    (10013)
.................................................................
LAYER MET6  ..... TOTAL Original Geometry Count = 0    (0)

这个文档是检查结果,行尾的数字是每个检查选项erro的数量,我想过滤出错误数不是0的行。
其实最简单的方法就是grep -v  '(0)',但是因为我一开始就想拧了。想这么匹配----括号以及括号中的内容:(开头不是0的数字,后面任意内容)
于是我用了grep'([1-9]*)',这个是有问题的:
1.首先我想用正则表达式,那么就得用egrep,我用的csh好像grep命令并不是支持所有正则表达式的形式。
$ echo "LAYER MET6 ..... 1 (12103)" | egrep '([1-9]+)'
LAYER MET6 ..... 1 (12103)

echo "LAYER MET6 ..... 1 (12103)" | grep '([1-9]+)'
没有输出结果

2. 我对括号没有用转意符\,我实际上是想匹配括号内的数字,如果没有转意符,那么会匹配括号外的数字。
$ echo "LAYER MET6 ..... 12103 (0)" | egrep '([1-9]+)'
LAYER MET6 ..... 12103 (0)
需要说明的是这个12103 (0)并不是在文件之中,而是我做实验的时候顺手输入的,文件之中只有两种形式,行尾的数字要么括号内和括号外都不为0,要么括号内和括号外都为0。所以还是用grep -v '(0)' 最简单,像我这样的初学者总是认为匹配越精确越好,其实思路错了。
$ echo "LAYER MET6 ..... 12103 (0)" | egrep '\([1-9]+\)'
没有输出结果

3.正则表达式中的*并非表示匹配任意字符,而是之前的结构出现任意次(包含0次)。 egrep '\([1-9]*\)'并不是我理解的,以括号中1-9的数字开头,然后后面随意匹配,而是,在括号内只有1-9这几个数字,出现N次,也可以是0次。
需要注意的一点是:虽然我做的某些实验命令输出结果是预想中的,但是并不是说匹配模式是对的。
$ echo "LAYER MET6 ..... 12103 (102)" | egrep '\([1-9]*\)'
没有输出,乍一看会以为这个匹配是对的,但是:
$ echo "LAYER MET6 ..... 12103 ()" | egrep '\([1-9]*\)'
LAYER MET6 ..... 12103 ()

4.关于匹配的理解,我一直很疑惑为什么$ echo "LAYER MET6 ..... 12103 (102)" | egrep '\([1-9]*\)'为什么会没有输出。于是输入了类似几个命令
$ echo "LAYER MET6 ..... 12103 (102)" | egrep '\([1-9]{1,}\)'
$ echo "LAYER MET6 ..... 12103 (102)" | egrep '\([1-9]+\)'
这两个命令也是没有输出,我就知道我的理解错了。最后琢磨明白了([1-9]{1,}、[1-9]+、[1-9]*,都是匹配1-9这几个数字,可以出现任意次(包括0次),但是数字中间不能有0。
$ echo "LAYER MET6 ..... 12103 (112)" | egrep '\([1-9]+\)'
LAYER MET6 ..... 12103 (112)

所以按照我的思路,最终正确的方法应该是用egrep '\([1-9].*\)' 来匹配
$ echo "LAYER MET6 ..... 12103 (102)" | egrep '\([1-9].*\)'
LAYER MET6 ..... 12103 (102)

$ echo "LAYER MET6 ..... 0 (102)" | egrep '\([1-9].*\)'
LAYER MET6 ..... 0 (102)

$ echo "LAYER MET6 ..... 12103 (0)" | egrep '\([1-9].*\)'
没有输出

走了一大圈弯路,但是我自认为还是值得的,至少把以前理解错误的地方纠正了。自学之所以难,就是因为有不明白的地方,有时候得花大量时间去琢磨去试验,但是如果有人帮忙答疑,就一句话的事儿,所以再次感谢几位老兄的解惑。


论坛徽章:
0
15 [报告]
发表于 2014-05-19 15:40 |只看该作者
回复 14# winteryxu

嘛,其实,输出最后一个()中的值大于0的行,直观上考虑,我大概会写成
awk -F'[()]' '$(NF-1)>0'
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP