- 论坛徽章:
- 2
|
本帖最后由 yinyuemi 于 2011-06-25 14:59 编辑
回复 1# Nalternative
这个问题很有趣,所以研究下,下面是我的理解,如果有不对的地方,请大家指正![]()
首先我觉得两段代码执行结果不同,原因比较简单,第二个代码因为使用了管道,所以相当于两个sed程序独立完成对文本的处理,第一个虽然使用了-e,但始终是在一个sed里完成的,这里我主要想说下为什么第一个代码会得出lz那样的输出结果。
(最初,我的觉得输出结果应该是,为什么3没有了呢?)
经过多次尝试,变化代码,最后发现问题的关键是第二个1,2这个匹配上,
sed -e '1,2d' -e '1,2d'
中的第一个1,2匹配没有问题,将第1和2行删除,
当执行到第二个1,2匹配的时候,由于第1和2行已经被删除,所以此时读入patten的行号为3,那么“1 ” 匹配是失败的,怎么还会把第三3行的数据删除呢?
原来是和line1,line2或/pattern/,line(line,/pattern/)这样的匹配模式有关,
1, 如果line和pattern匹配成功时,sed从line1匹配,直到line2或/pattern/
- seq 6 |sed -n '1,3p'
- 1
- 2
- 3
复制代码 2, 如果匹配不成功时,又有下面几种情况:
<a>, line=0时,只能使用0,/pattern/的模式,即从头匹配,直到pattern
- seq 6 |sed -n '0,/3/p'
- 1
- 2
- 3
复制代码 但下面的模式不能使用
- seq 6 |sed -n '0,3p'
- sed: -e expression #1, char 4: invalid usage of line address 0
复制代码 关于0,/pattern/的原文解释:A line number of 0 can be used in an address specification like 0,/regexp/ so that sed will try to match regexp in the first input line too. In other words, 0,/regexp/ is similar to 1,/regexp/, except that if addr2 matches the very first line of input the 0,/regexp/ form will consider it to end the range, whereas the 1,/regexp/ form will match the beginning of its range and hence make the range span up to the second occurrence of the regular expression.
<b>, line 匹配成功,/pattern/匹配不成功,则是,从line行到最后一行
- seq 6 |sed -n '3,/v/p'
- 3
- 4
- 5
- 6
复制代码 <c> 就是lz举的例子中第二个line1,line2的特殊匹配情况,下面我把具体执行过程写下,- seq 6 |sed -e '1,2'd -e '1,2'd
- 读入第一行,1,2匹配成功,执行d,删除第一行,
- 读入第二行,1,2匹配成功,执行d,删除第一行
- (这时,第一个-experssion执行完毕,执行第二个-experssion)
- 读入第三行,1,2匹配成功了一半,因为1匹配成功,这里可以像<a>中0一样,"try to match regexp in the first input line too",所以执行d,删除第三行。
- 读入第四行,1,2匹配失败,第二个experssion执行结束,
- 读入第五行,第六行,结束。
复制代码 为了更好的理解,结合前面<b>的情况,执行下面代码:
- line1=2
- seq 6|sed -e '1,3d' -e"$line1,3d"
- 5
- 6
- #看来只要line1小于当前读入的行号就判读成功,你可以试试line1等于3的情况
- seq 6 |sed -e '1,2d' -e"$line1,/v/d'
- #没有输入,因为/v/匹配失败,所以命令d会一直执行到最后一行,把所有行都被删除。
- seq 6 |sed -e '1,2d' -e"$line1,5d'
- 6
- #命令d只执行到第5行
复制代码 非常感谢lz的例子,让我对sed的模式匹配加深了理解![]()
最后再show两个和sed用法很类似的awk例子,呵呵
- seq 6 |awk '!i++,/3/'
- 1
- 2
- 3
-
- seq 6 |awk '/3/,0'
- 3
- 4
- 5
- 6
复制代码 你看懂了么? |
评分
-
查看全部评分
|