对于常常使用的sed命令,我们需要知道如下的内容,才能更好的使用它:
A.
模式空间: sed 在处理每一行的时候,首先会把要处理的行存入到模式空间里面;然后在模式空间中进行处理,处理完成后,把结果输出,然后释放模式空间。这个模式空间的概念可能听起来有点生疏,其实就是临时缓冲区;换个名称而已;对模式空间的使用举例:
通常把Linux下的文本文件换行符(\n)变为windows下的换行符号(\r\n), 我们不可以直接用:sed 's/\n/\r\n/' FILE , 因为“读入到模式空间”完成后,在模式空间里的行尾的换行符已经没有了,此时再进行替换操作,那么因为没有内容可以匹配而无法成功替换;
[root@localhost ~]# cat testfile.txt
12345
abcdefgs
ASK_MBG.
[root@localhost ~]# cat testfile.txt | od -An -txC
31 32 33 34 35 0a 61 62 63 64 65 66 67 73 0a 41
53 4b 5f 4d 42 47 2e 0a #结果中有三个0x0a, 表示3行;此为linux格式
[root@localhost ~]#
[root@localhost ~]# sed -i 's/\n/\r\n/' testfile.txt #直接替换是没有效果的;
[root@localhost ~]# cat testfile.txt | od -An -txC
31 32 33 34 35 0a 61 62 63 64 65 66 67 73 0a 41
53 4b 5f 4d 42 47 2e 0a #替换后的结果和替换前一样,因为根本没有匹配到
[root@localhost ~]#
要解决这个问题,需要用N命令,追加当前行的后一行的内容到模式空间,然后再做替换操作;因为把两行的内容同时放到模式空间之后, 此时只有模式空间末尾的换行符\n被剔除掉了,所以仍然可以匹配到前一行的换行符,从而实现替换;看下面的结果:
[root@localhost ~]# cat testfile.txt | od -An -txC
31 32 33 34 35 0d 0a 61 62 63 64 65 66 67 73 0a
41 53 4b 5f 4d 42 47 2e 0a #结果中有个0x0d0a, 表示第一行替换成功;
[root@localhost ~]#
[root@localhost ~]# sed -i '2,$N;s/\n/\r\n/' testfile.txt
[root@localhost ~]# cat testfile.txt | od -An -txC
31 32 33 34 35 0d 0a 61 62 63 64 65 66 67 73 0d
0a 41 53 4b 5f 4d 42 47 2e 0a #以双数作为开始行,那么这里第二行也替换成功
[root@localhost ~]#
**在上面的结果中,我们看到1,2行都替换成功,但是最后一行还是没有替换,为什么呢? **
因为是最后一行,所以自然没有下一行,也就不存在把下一行追加到模式空间的说法,所以也就无法替换,但是方法总比问题多:我们先在原始文件后面追加一个空行,然后再按照上面的方式处理就可以了。
[root@localhost ~]# wc -l testfile.txt
3 testfile.txt
[root@localhost ~]# sed -i '$a\ ' testfile.txt #表示在最后一行之后追加空格
[root@localhost ~]# wc -l testfile.txt
4 testfile.txt
[root@localhost ~]# cat testfile.txt
12345
abcdefgs
ASK_MBG.
[root@localhost ~]#
[root@localhost ~]# cat testfile.txt | od -An -txC
31 32 33 34 35 0a 61 62 63 64 65 66 67 73 0a 41
53 4b 5f 4d 42 47 2e 0a 20 0a #这里看到多了一个0x200a, 表示空格
B.
除了模式空间,还有一个概念叫做 hold space, 中文有叫做"保持空间”的,这也是一种缓冲区,这个缓冲区是不会自动release的;也不会自动把空间的内容进行输出;通常使用hold space的方式是: 在模式空间和hold space之间进行交互,具体有下列:
h H Copy/append pattern space to hold space. #把模式空间的内容 copy或者追加到hold space.
g G Copy/append hold space to pattern space. #把hold space的内容copy或者追加到模式空间
x Exchange the contents of the hold and pattern spaces. #交换模式空间和hold space的内容;
对于hold space的使用,有一个比较典型的例子是 实现tac的功能:
[root@localhost ~]# cat testfile.txt
12345
abcdefgs
ASK_MBG.
[root@localhost ~]# sed '1!G;h;$!d' testfile.txt
ASK_MBG. # 1!G表示除了第一行,把hold space的内容追加到模式空间
abcdefgs # h 表示把模式空间放到hold space.
12345 # $!除了最后一行,在把pattern的内容放到hold space后,都要删除模式空间的内容;
[root@localhost ~]# tac testfile.txt
ASK_MBG.
abcdefgs
12345
[root@localhost ~]#
上面介绍了hold space和pattern space的应用举例,希望你已经get到了哦!
本文原创,转载请注明出处
网友评论