请选择 进入手机版 | 继续访问电脑版
查看: 104|回复: 4

[经验分享] 基于sed使用总结说明

[复制链接]

签到天数: 103 天

[LV.6]签到达人

发表于 2018-9-30 16:39:03 | 显示全部楼层 |阅读模式
看上几篇帖子后,应该对sed已经有了一些概念,也许已经发现了sed的重点在于各选项和各命令是如何影响sed循环以及SCRIPT循环的。确实如此,在info sed文档中,虽然没有将这些工作机制详细描述,但各选项各命令说明中,在需要的时候都提到了这些细节,而我所做的只不过是将其系统性地描述出来、做一些深入,再给几个示例解释,并使用通俗易懂的循环结构来展示这些机制。

最后,验证前文"n"和"N"命令留下的疑问:"n"和"N"命令是先判断是否还有下一行,再自动输出的。也就是证明下面两个判断语句采用前者还是后者的问题。

ADDR1,ADDR2{              # "n" command
     if [ "$line" -ne "$last_line_num" ];then
         auto_print;
         remove_pattern_space;
         read next_line to pattern_space;
     else
         auto_print;
         remove_pattern_space;
         exit;
     fi
};

ADDR1,ADDR2{              # "n" command
         auto_print;
         remove_pattern_space;
         [ "$line" -ne "$last_line_num" ] && read next_line to pattern_space || exit;
};
虽然后者看上去代码更优化,但事实上采用的是前者。要证明这一点不太容易,好在我想出了下面的方法来证明。下面的示例中使用的是"N",它和"n"在判断逻辑上的行为是一致的。

[root@xuexi ~]# echo -e "abc\ndef\nxyz" | sed '/def/{a\   
haha
;N}'

abc
haha
def
xyz

[root@xuexi ~]# echo -e "abc\ndef" | sed '/def/{a\     
haha
;N}'

abc
def
haha
在以上两个命令中,第一个命令"haha"是插入在匹配行"def"的前面,而第二个命令则是插入在"def"的后面。似乎根据"a"命令的作用来说,第二个命令才是意料之中的结果。

首先,解释第一个命令为何"haha"会出现在匹配行"def"的前面。当sed读取的行能匹配"def"时,将队列化"haha"到内存中,并在有输出流的时候追加到输出流尾部。由于这里的输出流来自于"a"命令后的"N"命令,该命令将模式空间锁住,使得隐含动作自动输出的内容为空,但队列化的内容还是发现了这个空输出流,于是追加在这个空流的尾部。再之后,"N"将下一行读取到模式空间中,到了SCRIPT循环的结尾,再次自动输出,此时模式空间有两行:"def" 和 "xyz",这两行同时被输出。显然,在"def"被输出之前,队列化的内容已经随着空输出流而输出了。

再解释为何第二个命令的结果中"haha"在"def"之后,这也是待证明的疑问。第二个命令中,由于"def"已经是输入流的最后一行,"N"已经无法再读取下一行,于是输出当前模式空间内容并退出sed程序。假设,"n"或"N"命令是先自动输出、清空模式空间内容,再判断是否有下一行可读取的,那么在判断之前自动输出时,"N"不知道是否还有下一行,于是队列化的内容应该同第一个命令一样,插入在"def"之前。但结果却并非如此。如果先判断是否有下一行可供读取,再输出、清空模式空间,则队列化内容是跟随着"N"退出sed程序前输出的,这正符合第二个命令的结果。

签到天数: 673 天

[LV.9]元老将成

发表于 2018-10-8 08:31:29 | 显示全部楼层
不错的资料
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

返回顶部