免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 24379 | 回复: 37
打印 上一主题 下一主题

sed能直接识别的RE……(初学sed必看)!  关闭 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-08-25 12:05 |只看该作者 |倒序浏览
本帖最后由 shaoping0330 于 2012-07-18 15:25 编辑

小弟在sed使用中,对正则表达式有几个地方犯迷糊,为了彻底弄明白,试验之……
特将结果呈与各位,请师兄们批评指正!也让初学者少走弯路。
虽说有些问题在明白之后,感觉很简单,贴出来好像没必要;但在明白之前,的确很让人糊涂,所以还是决定贴出来。

In basic regular expressions the metacharacters ?, +, {, |,  (,  and  ) lose  their  special  meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \).
---以上来自man grep 中的REGULAR EXPRESSIONS


正则表达式中的限定符:
*        匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+        匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
?        匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。
{n}        n是一个非负整数。匹配确定的n次。例如,'o{2}' 不能匹配"Bob"中的'o',但是能匹配"food"中的两个o。
{n,}        n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。
{n,m}        m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

\d        匹配一个数字字符。等价于 [0-9]。
\D        匹配一个非数字字符。等价于 [^0-9]。
\w        匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W        匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。


PS:linux 9 +sed-4.0.5-1
$ cat text
1*
1+
1?
1.
^1
1$
1{}
1{0,}
1{1,}
1{1,10}
1()
1[]
1[a-z]
1[^a-z]
1[a-z$]
1111
222222
1a
1bb
1\\
aaa aa aa
boy\gire\people
boy3gire5people
boy4gire9people
x|y
aab|cddd
212
21\
t\w
t\W
y\d
y\D

$ cat text |sed -n '/1*/p'
将显示text所有内容,因为sed能直接识别正则表达式符号 * ,/1*/ 意思是与包括1和不包括1的所有行匹配。

$ cat text |sed -n '/1\*/p'
仅显示 1* 这一行, * 在转义之后只是一个普通字符。

$ cat text |sed -n '/1+/p'
仅显示 1+ 这行,因为sed并不能直接识别 + ,只是把它当作一个普通字符。

$ cat text |sed -n '/1\+/p'
显示所有含一个及以上 1 的行, + 在转义后,成为正则表达式。

$ cat text |sed -n '/1?/p'
仅显示 1?  这行,因为sed并不能直接识别正则表达式符合 ? ,只是把它当作一个普通字符。

$ cat text |sed -n '/1\?/p'
显示所有的行,/1\?/ 与包括1和不包括1的所有行均匹配。

$ cat text |sed -n '/1./p'
显示所有含1的行,因为sed能直接识别正则表达式符号“ . ” 。

$ cat text |sed -n '/1\./p'
仅显示匹配 1.  的这行,“ . ”在转义后仅是一普通字符。

$ cat text |sed -n '/^1/p'
显示所有以 1 开头的行,因为sed能直接识别正则表达式符合 ^ 。

$ cat text |sed -n '/\^1/p'
显示 ^1 这一行, ^ 在转义后仅是一普通字符。

$ cat text |sed -n '/1$/p'
显示所有以 1 结尾的行,因为sed能直接识别正则表达式符号 $ 。

$ cat text |sed -n '/1\$/p'
显示 1$ 这一行, $ 在转义后仅是一普通字符。

$ cat text |sed -n '/1{}/p'
仅显示 1{} 这一行,因为sed并不能直接识别正则表达式符合{}。
$ cat text |sed -n '/1{1,}/p'
原理同上
$ cat text |sed -n '/1{1,10}/p'
原理同上
$ cat text |sed -n '/1{0,}/p'
原理同上
$ cat text |sed -n '/1()/p'
原理同上

$ cat text |sed -n '/1\{2,\}/p'
在转义之后,{} 在sed中具有 正则表达式限定符 功能,故显示两个及以上 1 的行。
$ cat text |sed -n '/1\{0,\}/p'
原理同上,显示所有含1及不含1 的行。

$ cat text |sed -n '/1[]/p'
报错“sed: -e expression #1, char 6: Unterminated address regex”,因为sed能直接识别正则表达式符号 [] ,但 [] 中间却为空,没有相关集合(字母或数字),故错。

$ cat text |sed -n '/1\[\]/p'
显示 1[] 这一行, []在转义后仅是普通字符。

$ cat text |sed -n '/1[0-9]/p'
1{1,10}
1111
不过我不明白为何会跑出第一行?难道是我的机器有毛病???——原因是 /1[0-9]/与{1,10}中的 “10”匹配!

$ cat text |sed -n '/1[^0-9]/p'
显示出所有含1 ,并且 1 后面非数字的行。

$ cat text |sed -n '/boy\gire\people/p'
无显示。因为sed不知道 \g \p 是什么,找不到匹配的东东!

$ cat text |sed -n '/boy\\gire\\people/p'
显示包含 boy\gire\people 的这一行,第一个\ 把紧随的 \ 转义成普通字符。

$ cat text |sed -n '/boy[0-9]/p'
boy3gire5people
boy4gire9people

但是
$ cat text |sed -n '/boy\d/p'
$ cat text |sed -n '/boy\d\{1\}/p'
却都没有显示,\d 不是等价于 [0-9] 。这里为甚么没显示?
\d \D \w \W 在使用时我还没有找到窍门,还请各位指教!

本人测试后,发现:
\w  在sed中好像只等价于'[A-Za-z_]'   ——老版本sed的bug,目前正常【120718】
\W 在sed中好像只等价于'[^A-Za-z_]'  ——老版本sed的bug,目前正常【120718】
\d  在sed中等价于'd'   ——只有 \dXXX
\D  在sed中等价于'D'   ——无这个
\s 在sed中等价于's'  ——老版本sed的bug,目前正常【120718】
\S 在sed中等价于'S'
  ——老版本sed的bug,目前正常【120718】

$ cat text |sed -n '/b|c/p'
显示 aab|cddd 这一行。sed把 | 当作普通字符。
$ cat text |sed -n '/x|y/p'
显示 x|y 这一行。sed把 | 当作普通字符。

$ cat text |sed -n '/aab\|212/p'
aab|cddd
212
|在转义之后表示 “或”的功能,对匹配aab 或 212 的行进行显示。

小结:
sed中可直接使用的RE:
*  .  ^  $  [  ]  \  c
\w ( 相当于[A-Za-z_] )  \W ( 相当于[^A-Za-z_] )
sed中需转义使用的RE:
+  ?  {  }  (  )  |  <  >
其他:
\d (d)  \D (D)  \s (s)  \S (S)
匹配 单引号’ 用双引号
匹配 反引号` 用单引号
\b 匹配单词的前或后边界 ( 字符[^A-Za-z0-9_]均构成单词边界 )
\B 匹配单词的非边界 ( 字符[^A-Za-z0-9_]均构成单词边界 )
\< 匹配单词的位置前 ( 字符[^A-Za-z0-9_]均构成单词边界 )
\> 匹配单词的位置后 ( 字符[^A-Za-z0-9_]均构成单词边界 )
支持十进制,格式为“\d + 两位或三位十进制数”,如“\d065 或\d65 均代表字符 A ”
支持十六进制,格式为“\x + 两位十六进制数”,如“\x61 代表字符 A ”
支持八进制,格式为“\o + 两位或三位八进制数”,如“\o077 或\o77 均代表字符 ?,\o101代表字符 A ”




大家快来砸砖吧!

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2004-08-25 12:21 |只看该作者

sed能直接识别的RE……(初学sed必看)!

不錯不錯! 加精鼓勵!  ^_^

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
3 [报告]
发表于 2004-08-25 12:21 |只看该作者

sed能直接识别的RE……(初学sed必看)!

不錯不錯! 加精鼓勵!  ^_^

论坛徽章:
0
4 [报告]
发表于 2004-08-25 12:52 |只看该作者

sed能直接识别的RE……(初学sed必看)!

谢谢netman的鼓励!

在写这篇的过程中,自己也学到很多。看来“帮助别人,就是帮助自己!”这话很有道理哦!

论坛徽章:
0
5 [报告]
发表于 2004-08-26 09:15 |只看该作者

sed能直接识别的RE……(初学sed必看)!

sed和awk只支持下列转义字符
\y, \B, \<, \>, \w, \W, \`, and \'
详情请看man awk

论坛徽章:
0
6 [报告]
发表于 2004-08-26 11:57 |只看该作者

sed能直接识别的RE……(初学sed必看)!

hehe学习

论坛徽章:
0
7 [报告]
发表于 2004-08-26 15:27 |只看该作者

sed能直接识别的RE……(初学sed必看)!

精彩

论坛徽章:
0
8 [报告]
发表于 2004-08-27 08:20 |只看该作者

sed能直接识别的RE……(初学sed必看)!

原帖由 "shaoping0330" 发表:

本人测试后,发现:
\w 在sed中好像只等价于'[A-Za-z_]'
\W 在sed中好像只等价于'[^A-Za-z_]'
\d 在sed中等价于'd'
\D 在sed中等价于'D'
\s 在sed中等价于's'
\S 在sed中等价于'S'


后生可畏,精神可嘉, 一年半载之后, 又是一个 XXgirl.  真乃 shell 坛之福也。

对于 sed 4.0.5

1. 没有 \D

2. 没有 \d, 只有 \dXXX.  例如 \d097 也就是字符  a

3.  \W, \w, \S, \s  没有正常工作, 这是 4.0.5 的 bug# 09022.
可能在 sed-4.0.7-2 中解决。

题外话: 各位用 GNU 工具多了,也有不好的地方,那就是 GNU 扩展太多,
与其他平台不兼容, 不利于跨平台使用。

论坛徽章:
0
9 [报告]
发表于 2004-08-27 10:54 |只看该作者

sed能直接识别的RE……(初学sed必看)!

$ cat text |sed -n '/1*/p'
将显示text所有内容,因为sed能直接识别正则表达式符号 * ,/1*/ 意思是与包括1和不包括1的所有行匹配。

个人观点:如果能识别*的话,应该是只与包括1所有行匹配吧??

论坛徽章:
0
10 [报告]
发表于 2004-08-27 11:03 |只看该作者

sed能直接识别的RE……(初学sed必看)!

*的意思是 0个或多个,所以有 1 和没1 的均显示。
你试试就知道了 ^_^
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP