免费注册 查看新帖 |

Chinaunix

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

关于sed替换的一点自我体会 [复制链接]

论坛徽章:
0
发表于 2005-04-22 10:43 |显示全部楼层
偶尔在一个shell脚本里面看到了一个类似sed 's/(\(.*\))/\1\1/'这样的语句,鉴于对shell不是非常熟悉,所以也就没有看懂,后来理解了一下,还算明白一二,贴出来理解过程,为与兄弟姐妹们交流。
其实这个sed替换就是针对含有括号的情况
比如下面会提到的
no1=100(AAA) no2=100(BBB) no3=100(CCC) no4=(DDD)
其中AAABBBCCCDDD都是变化的,我们要提取AAA或者BBB的情况

首先理解一个()的情况
举个例子:
[root@mail root]# echo "111(222)333"| sed 's/(\(.*\))/\1\1/'
111222222333

因为(\(.*\)只有这一个部分,所以\1就意味着这一个部分提取两次(如果是\2就应该提不到东西)

[root@mail root]# echo "111(222)333"| sed 's/(\(.*\))/\1\2/'
sed:-e 表达式 #1,字符 16:Invalid reference \2 on `s' command's RHS

由于(不是元字符,所以直接写(就表示(这个符号,而\(才表示包含什么的意思


而又因为是()里面的内容,所以将222提取两次

如果将()去掉,例如
[root@mail root]# echo "111(222)333"| sed 's/\(.*\)/\1\1/'
111(222)333111(222)333
那么提取的匹配就是这个部分了

-------------------------------------
[root@mail root]# echo "111(222)333"| sed 's/\(.*\)(\(.*\))/\1\1\1/'
111111111333
因为//里面是由\(.*\) 和 (\(.*\))两部分组成,而\1仍然是提取第一部分,也就是(222)前的所有内容和(222)这个整个部分替换为(222)前的所有内容提取三次,其后的333不变

[root@mail root]# echo "111(222)333"| sed 's/\(.*\)(\(.*\))/\2\2\2/'
222222222333
将(222)前的所有部分和(222)看成一个整体,被替换为()内的部分,也就是222。

此处理解\2\2\2,2的含义应该是提取第二个\(.*\)即:“第二个包含” 得意思也就是:(将()换成yy也是一样得含义)
[root@mail root]# echo "111y222y333"| sed 's/\(.*\)y\(.*\)y/\2\2\2/'
222222222333

-------------------------------------
两个括号及其以上得情况:

[root@mail root]# echo "no1=100(AAA) no2=100(BBB) no3=100(CCC) no4=(DDD)" | sed 's/\(.*\)(\(.*\)).*/\2/'
DDD
[root@mail root]# echo "no1=100(AAA) no2=100(BBB) no3=100(CCC) no4=(DDD)" | sed 's/.*(\(.*\)).*/\1/'
DDD
以上两句意义相同。
我们本想取到AAA,但是为什么取了DDD呢
正则表达式是有贪婪性的,它总是与最长的可能长度匹配,而且越是排在前面的通配符优先级越高。按照这样的原则取到得就是DDD了,那么我们应该如何取得AAA呢?

我们考虑如果在模式串中第一个.*中告诉sed这个.*是不能含有"("的,同时第二个.*中不能含有""应该OK吧
试一试:
[root@mail root]# echo "no1=100(AAA) no2=100(BBB) no3=100(CCC) no4=(DDD)" | sed 's/[^(]*(\([^)]*\)).*/\1/'
AAA

以此类推,可以得到
[root@mail root]# echo "no1=100(AAA) no2=100(BBB) no3=100(CCC) no4=(DDD)" | sed 's/[^(]*(\([^)]*\))[^(]*(\([^)]*\))[^(]*(\([^)]*\))[^(]*(\([^)
]*\))/\2/'
BBB
将2改为3就是CCC
将3改为4就是DDD

就体会这些内容花了我一晚上,google了没有发现这方面的什么东西(呵呵,那位有什么详解之类让俺也借鉴一下),不过主要还是觉得shell不够熟练,呵呵,好多符号不知其意,都是现查。兄弟姐妹们看看哪里体会的有问题或是不够完善,小弟在此多谢执教了。

论坛徽章:
0
发表于 2005-04-22 11:25 |显示全部楼层

关于sed替换的一点自我体会

up,up,精华吧。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
发表于 2005-04-22 12:51 |显示全部楼层

关于sed替换的一点自我体会

原帖由 "zzzzzjjjjj" 发表:
)/\2/'
BBB
将2改为3就是CCC
将3改为4就是DDD

就体会这些内容花了我一晚上,google了没有发现这方面的什么东西(呵呵,那位有什么详解之类让俺也借鉴一下),不过主要还是觉得shell不够熟练,呵呵,好多符号不..........

  
在本版精华区里有sed1line的精华贴,那贴真不错!

论坛徽章:
0
发表于 2005-04-22 13:43 |显示全部楼层

关于sed替换的一点自我体会

哈哈,看了,是不错,不过。。。。内容好多啊

论坛徽章:
0
发表于 2005-04-22 14:34 |显示全部楼层

关于sed替换的一点自我体会

俺写不出长篇大论,因此支持

论坛徽章:
0
发表于 2005-04-26 00:27 |显示全部楼层

关于sed替换的一点自我体会

烈火兄  可否把CU里你说的那篇精华的具体网址告我啊   发到我油箱里  谢谢  烈火大哥    llljj19821229@yahoo.com.cn

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
发表于 2005-04-26 00:30 |显示全部楼层

关于sed替换的一点自我体会

[quote]原帖由 "60133056"]烈火兄  可否把CU里你说的那篇精华的具体网址告我啊   发到我油箱里  谢谢  烈火大哥    llljj19821229@yahoo.com.cn[/quote 发表:

http://bbs.chinaunix.net/forum/viewtopic.php?t=336126

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
发表于 2005-05-17 17:02 |显示全部楼层

关于sed替换的一点自我体会

不错!支持,
BTW:sek与awk实践大师书上有提到!

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
发表于 2005-05-17 17:03 |显示全部楼层

关于sed替换的一点自我体会

原帖由 "wingger" 发表:
不错!支持,
BTW:sek与awk实践大师书上有提到!

wingger法师最近少见呀 ?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
发表于 2005-05-17 19:21 |显示全部楼层

关于sed替换的一点自我体会

原帖由 "寂寞烈火" 发表:

wingger法师最近少见呀 ?


水平不好,不好意思出来现丑了           

再修炼修炼
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP