先来说说sed命令的原理和一些概念,sed之所以能以行为单位的编辑或修改文本,其原因在于它使用了两个空间:一个是活动的“模式空间(pattern space)”,另一个是起辅助作用的“暂存缓冲区(holdingspace)这2个空间的使用。
模式空间:sed处理文本内容行的一个临时缓冲区,模式空间中的内容会主动打印到标准输出,并自动清空模式空间
保持空间:sed处理文本内容行的另一个临时缓冲区,不同的是保持空间内容不会主动清空,也不会主动打印到标准输出,而是需要sed命令来进行处理
模式空间与保持空间的关系 模式空间:相当于流水线,文本行在模式空间中进行处理; 保持空间:相当于仓库,在模式空间对数据进行处理时,可以把数据临时存储到保持空间;作为模式空间的一个辅助临时缓冲区,但又是相互独立,可以进行交互,命令可以寻址模式空间但是不能寻址保持空间。可以使用高级命令h,H,g,G与模式空间进行交互。
可能看完这两个概念,还是比较难懂,这里我们使用一个例子来说明一下。
sed执行模板如下:
sed ‘模式{命令1;命令2}’
即逐行读入模式空间,执行命令,最后输出打印出来.
01
n命令和N命令
首先来说n命令:
这个命令简单来讲就是读取下一行,覆盖模型空间的上一行,然后执行后续命令。用法如下:
读取文件中的偶数行
[dba_mysql /tmp]$cat aaa.txt
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
[dba_mysql /tmp]$cat aaa.txt|sed -n 'n;p'
this is line ;
this is line ;
this is line ;
这里需要注意,sed -n里面的n指代的是--quiet或者--slient模式,它不更改文件本身,只会把修改后的结果打印出来,如果要直接修改文件,我们需要将-n修改为-i。
sed -n 'n;p'第二个n才是n命令的位置,它的意思是提前读取下一行,也就是偶数行,然后执行p命令,也就是打印。
再来说说N命令:
N命令简单来说就是追加下一行到模式空间,同时将两行看做一行,但是两行之间依然含有\n换行符,然后执行后续命令。这里有一个典型的例子,想要去掉某个语句块中最后一行的逗号,如下:
[yeyz ~]$ cat file
yeyz{
yeyzdd,
yeyzdd,
yeyzdd,
yeyzdd,
}
[yeyz ~]$ cat file | sed 'N; s/,\n}/\n}/'
yeyz{
yeyzdd,
yeyzdd,
yeyzdd,
yeyzdd
}
也就是说,它将下一行和本行作为一行来理解,然后两行之间仍然有\n的换行符,然后使用s命令替换,\n}为\n},这样就解决了我们的问题。
02
匹配行前后一行插入数据a参数和i参数
a代表after
i代表in front
他们的使用方法也比较简单,我们举例子可以看到:
[dba_mysql /tmp]$cat aaa.txt
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
[dba_mysql /tmp]$sed -i '/line 3/a\first' aaa.txt
[dba_mysql /tmp]$cat aaa.txt
this is line ;
this is line ;
this is line ;
first
this is line ;
this is line ;
this is line ;
[dba_mysql /tmp]$sed -i '/line 3/i\second' aaa.txt
[dba_mysql /tmp]$cat aaa.txt
this is line ;
this is line ;
second
this is line ;
first
this is line ;
this is line ;
this is line ;
我们使用a参数在匹配行的后面添加first字样,使用i参数在匹配行的后面添加second字样。
03
d命令是删除当前模式空间内容(不再传至标准输出),并放弃之后的命令,并对新读取的内容,重头执行sed。
[dba_mysql /tmp]$cat aaa.txt
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
[dba_mysql /tmp]$sed 'n;d' aaa.txt
this is line ;
this is line ;
this is line ;
可以看到,我们是用n命令,先找到偶数行,然后使用d命令进行删除,最后得到了奇数行的结果。执行过程如下:读取1,执行n,得出2,执行d,删除2,得空,以此类推,读取3,执行n,得出4,执行d,删除4,得空,读取5,执行n,得出6,执行d,删除6,因无-n参数,故输出1\n3\n5
D命令是删除当前模式空间开端至\n的内容(不在传至标准输出),放弃之后的命令,但是对剩余模式空间重新执行sed
[dba_mysql /tmp]$cat aaa.txt
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
[dba_mysql /tmp]$sed 'N;D' aaa.txt
this is line ;
它相当于将所有的行都拼接了起来,然后删除开始到\n的内容,并循环执行,所以最后只剩下了最后一行的内容。
04
G命令
[dba_mysql /tmp]$cat aaa.txt
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
[dba_mysql /tmp]$cat aaa.txt | sed G
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
this is line ;
[dba_mysql@tk-dba-redismgmt243 /tmp]$
上面的例子说明了G命令是给不为空的行下面添加一个空行,为什么会添加一个空行呢?是因为G命令本身的作用是将为空的hold space附加到文件的每一行后面,所以结果是每一行后面多了一个空行。