Chinaunix

标题: 关于sed替换的一点自我体会 [打印本页]

作者: zzzzzjjjjj    时间: 2005-04-22 10:43
标题: 关于sed替换的一点自我体会
偶尔在一个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不够熟练,呵呵,好多符号不知其意,都是现查。兄弟姐妹们看看哪里体会的有问题或是不够完善,小弟在此多谢执教了。
作者: ga0feng    时间: 2005-04-22 11:25
标题: 关于sed替换的一点自我体会
up,up,精华吧。
作者: 寂寞烈火    时间: 2005-04-22 12:51
标题: 关于sed替换的一点自我体会
原帖由 "zzzzzjjjjj" 发表:
)/\2/'
BBB
将2改为3就是CCC
将3改为4就是DDD

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

  
在本版精华区里有sed1line的精华贴,那贴真不错!
作者: zzzzzjjjjj    时间: 2005-04-22 13:43
标题: 关于sed替换的一点自我体会
哈哈,看了,是不错,不过。。。。内容好多啊
作者: 一梦如是    时间: 2005-04-22 14:34
标题: 关于sed替换的一点自我体会
俺写不出长篇大论,因此支持
作者: 60133056    时间: 2005-04-26 00:27
标题: 关于sed替换的一点自我体会
烈火兄  可否把CU里你说的那篇精华的具体网址告我啊   发到我油箱里  谢谢  烈火大哥    llljj19821229@yahoo.com.cn
作者: 寂寞烈火    时间: 2005-04-26 00:30
标题: 关于sed替换的一点自我体会
[quote]原帖由 "60133056"]烈火兄  可否把CU里你说的那篇精华的具体网址告我啊   发到我油箱里  谢谢  烈火大哥    llljj19821229@yahoo.com.cn[/quote 发表:

http://bbs.chinaunix.net/forum/viewtopic.php?t=336126
作者: wingger    时间: 2005-05-17 17:02
标题: 关于sed替换的一点自我体会
不错!支持,
BTW:sek与awk实践大师书上有提到!
作者: 寂寞烈火    时间: 2005-05-17 17:03
标题: 关于sed替换的一点自我体会
原帖由 "wingger" 发表:
不错!支持,
BTW:sek与awk实践大师书上有提到!

wingger法师最近少见呀 ?
作者: wingger    时间: 2005-05-17 19:21
标题: 关于sed替换的一点自我体会
原帖由 "寂寞烈火" 发表:

wingger法师最近少见呀 ?


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

再修炼修炼
作者: 云飞舞    时间: 2005-05-17 19:34
标题: 关于sed替换的一点自我体会
原帖由 "wingger" 发表:


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

再修炼修炼

姐姐是最棒的,我支持你!
作者: jinfengwu_2006    时间: 2010-10-19 09:05
写得真不错,对sed替换这块真的不了解,而且正在学习,你的总结对我很大帮助,学习了!
作者: xindi10631    时间: 2010-10-19 12:04
不错,学习了!
作者: lnitcscq    时间: 2010-10-28 22:55
看不太懂,先收藏学习。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2