这个问题我相信很多同学困扰了很久,懂的大师们早已熟练于心,不懂的小鸟们百思不解。今天我就彻底的分析透彻这2个命令的区别,和在什么场合下使用。我们首先看看它们的区别:
$ seq 5
1
2
3
4
5
$ seq 5 | sed -n 'N;P' #命令⑴
1
3
$ seq 5 | sed -n '$!N;P' #命令⑵
1
3
5
N的作用是读取下一行的内容到模式空间(pattern space),阁下可以理解为sed这时候把两行读入成中间带\n的一行内容,原本sed的执行原理是逐行读取到模式空间,N呢就促使sed把下一行内容也同时读取到模式空间待命。在命令⑴中,这时候N就让sed把1、2行同时读入了模式空间,P是打印模式空间第一行内容,这时候1就输出到了屏幕,接着读入3、4行输出3到屏幕上,到了最后一行第5行,为什么没有输出呢?原来N还有另外一个特性:当无法处理下一行内容时,N则会中止退出,所以后面的命令也不会再执行。这就不难解释为什么没有输出第5行了,到了最后一行已经没有下一行处理了,所以N就退出命令,后面的P也不会执行,这时候如命令⑵:$!N 对最后一行不再执行N命令,则会继续执行命令P,打印模式空间的第一行,5就输出到了屏幕。那么下面的命令怎么又没有区别呢?$ seq 5 | sed 'N;s/\n/ /' #命令⑶
-
1 2
3 4
5
$ seq 5 | sed '$!N;s/\n/ /' #命令⑷
1 2
3 4
5
-
为什么呢?大家注意观察该sed没有参数 -n,原因就在这里,sed是默认输出模式空间里的内容,当执行到最后一行时,命令⑶的N无法处理下一行内容,就退出了命令,不执行后面的替换语句,但是sed默认会输出该行内容,所以5仍然输出到了屏幕上。命令⑷中呢,到了最后一行,N没起作用,后面的替换执行也是不成功的,但sed还是会默认输出该行内容,5也出现在了屏幕上,最后两个命令的结果一样,但是过程是不一样的。我再重复一下:命令⑶执行到最后一行时N中止了命令,sed默认输出了该行内容,而命令⑷则执行了后面的替换动作,只是替换不成功没起到任何作用,sed也仍然输出了该行内容。大家明白了吗?我们也可以加 -n 参数就可以看出差别了:
-
$ seq 5 | sed -n 'N;s/\n/ /;p'
1 2
3 4
$ seq 5 | sed -n '$!N;s/\n/ /;p'
1 2
3 4
5
加了 -n 参数后,N中止了命令,后面的p也没有执行,所以第5行没有输出,而 $!N 会对最后一行不操作,N没有起作用,所以没有中断后面的语句执行,p把5输出到了屏幕上。
总结:N 和 $!N 有时候结果并没有差异,那是因为sed默认是输出模式空间内容的。当有 -n 参数时大家就要注意它们两个之间的运用了。
看完这篇博文的同学我想已经彻底搞清楚了N的作用了,谢谢大家对我博客的关注。好记性不如烂笔头^_^
阅读(7070) | 评论(0) | 转发(3) |