Linux命令之sed 在开始写文章之前,再次重复那句话:sed,grep和awk被称之为Linux三剑客。这句话我一直在强调,足以说明这三个命令在linux中的重要性,废话不多说,今天我们来看看sed的一些操作。

先来说说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命令简单来说就是追加下一行到模式空间,同时将两行看做一行,但是两行之间依然含有 换行符,然后执行后续命令。这里有一个典型的例子,想要去掉某个语句块中最后一行的逗号,如下:

[yeyz ~]$ cat file
yeyz{
    yeyzdd,
    yeyzdd,
    yeyzdd,
    yeyzdd,
}
[yeyz ~]$ cat file | sed 'N; s/,
}/
}/'
yeyz{
    yeyzdd,
    yeyzdd,
    yeyzdd,
    yeyzdd
}

也就是说,它将下一行和本行作为一行来理解,然后两行之间仍然有 的换行符,然后使用s命令替换, }为 },这样就解决了我们的问题。

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/afirst' 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/isecond' 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命令和D命令

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 3 5

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 ;

它相当于将所有的行都拼接了起来,然后删除开始到 的内容,并循环执行,所以最后只剩下了最后一行的内容。

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附加到文件的每一行后面,所以结果是每一行后面多了一个空行。

收藏 打印