一、sed概述

二、sed处理流程

 

三、sed命令使用

四、sed使用示例

五、sed与vim,awk,grep的比较

 

 

一、sed概述

 

sed是Stream EDitor的缩写,意为流式文本编辑器。sed名字来源于其功能,可以想象污水流经污水处理点后流出更为干净的水,sed也一样,文本中的数据流可以使用sed这个文本处理工具中各种编辑命令进行处理,最终以另一种格式输出。

 

sed是一种'非交互式'的编辑器,一次只处理一行内容。在处理时,会先将待处理的一行暂存至内存中的某一段缓存空间,这段缓存空间称为“模式空间(Pattern Space)”。接着使用sed命令处理模式空间中的内容,而处理后的内容默认输出至标准输出,默认不修改原文件。然后接着处理下一行,直至最后一行。sed常用来重复编辑一个或多个文件,简化对文件的操作。

    

此外,除了"模式空间(Pattern Space)",sed在使用一些高级命令(例如:g/G, h/H, x)时还会使用到保持空间(Hold Space),保持空间用于保存模式空间的内容,但不管模式空间和保持空间如何工作,最终只能由模式空间输出至标准输出。

 

wKioL1ilCnyikXs4AABcmf2eTD4534.png

 

spacer.gif

二、sed处理流程

 

当我们指定用sed命令去处理某个文件时,其处理流程如下:

1
2
3
4
5
6
① 读入新的一行进入模式空间(pattern space);
② 从指定的操作指令中取出第一条指令,判断该行是否被pattern匹配;
③ 如果不匹配,则忽略后续的编辑指令,在静默模式下不会输出,否则默认输出;
④ 如果匹配,并针对缓存的行执行后续的编辑命令。执行后,返回第2步继续取出下一条指令。
⑤ 当应用所有指令后,将模式空间中缓存的处理结果输出;返回第1步读取文本的下一行;
⑥ 当所有行都处理之后,结束。

 

wKiom1ilCnzARFz9AACEFoyRn5g259.png

 

总结一下,sed的处理是这样的:把要处理的一行放进模式空间中,先看看是否要默认输出这一行至标准输出;接着对模式空间匹配到的行进行处理(执行一个或一个以上的编辑命令);最后再把模式空间中匹配到的行的处理结果输出至标准输出。

 

三、sed命令使用

 

命令格式:

1
2
sed [option]... 'script' [FILE]...
sed 选项 '地址定界编辑命令' 文件

 

常用选项:

    -n:静默模式,抑制默认输出;

    -r:支持使用扩展正则表达式元字符;、

    -i:直接修改原文件;

    -i.bak:直接修改原文件,但会生成一个原文件的备份文件(后缀名为.bak)

    -e:用于实现多个'script'一次执行;

    -f /PATH/TO/SED_SCRIPT_FILE:可使用sed脚本文件来执行对文本的处理操作。

 

地址定界:

(1)不接地址:全局应用于每一行,即匹配所有行;

(2)单地址:

N:第N行;

/pattern/:由pattern匹配到的行;

$:最后一行;

(3)地址范围:

M,N:从第M行到第N行之间的所有行;

M,+N:从第M行开始到M+N之间的所有行;

N,$:从第N行到最后一行之间的所有行;

M,/pattern/:从第M行到由pattern第一次匹配到的行之间的所有行;

/pattern1/,/pattern2/:从由pattern1第一次匹配到的行到由pattern2第一次匹配到的行之间的所有行;

(4)步进表示法:

1~2:所有奇数行;例如: sed '1~2p' test

2~2:所有偶数行;例如: sed '2~2p' test

 

编辑命令:

编辑命令是对模式空间中匹配到的行进行编辑处理操作。编辑命令有基本命令和高级命令,基本命令一次只能处理一行,而高级命令可实现一次处理多行(或理解为将多行视为一行来处理)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
(a)基本命令:
    d:delete, 删除模式空间中匹配到的行;
    p:print, 显示模式空间中被匹配到的行;
    a \TEXT:append, 在指定行后追加文本TEXT,支持使用\n实现多行追加;
    i \TEXT:insert, 在指定行前插入文本TEXT,支持使用\n实现多行插入;
    c \TEXT:将指定行的内容替换为文本TEXT;
    /PATH/TO/SOMEFILE:write, 保存模式空间中匹配到的行至指定的文件中;
    /PATH/FROM/SOMEFILEread, 将指定文件的内容读取至当前模式空间中被匹配到的行后面,
    常用于实现文件合并;
    s/pattern/replaces/:查找替换;分隔符可自行指定,常用的分隔符有/, #, @等;
        替换标记:
            g:全局替换;
            /PATH/TO/SOMEFILE:将替换的结果保存至指定文件中;
            p:显示替换成功的行;
    y:用于(对应)转换字符;
    =:打印行号;
    !:条件取反;即对不被模式匹配到的行执行编辑命令;格式为:地址定界!编辑命令
    l:打印行号,并显示控制字符;
    q:读取匹配到的行后退出;
     
     · 
(b)高级命令:
    n:覆盖读取匹配到的行的下一行至模式空间中;
    N:追加读取匹配到的行的下一行至模式空间中,并用\n连接两行;
    D:删除模式空间的第一行的内容,并在模式空间中继续执行编辑命令;
    P:打印模式空间的第一行的内容;
    h:hold, 将模式空间中的内容覆盖至保持空间中;
    H:Hold, 将模式空间中的内容追加至保持空间中;
    g:get, 将保持空间中的内容覆盖至模式空间中;
    G:Get, 将保持空间中的内容追加至模式空间中;
    x:exchange, 将模式空间中的内容与保持空间中的内容互换;
     
     
注意:
(1) sed保持空间(Hold Space):用于保存模式空间的内容;
(2) h, H, g, G, x这5个高级命令会使用到sed的保持空间;

 

四、sed使用示例

 

4.1. 以行为单位新增/删除

 

将/etc/passwd的内容输出并且打印行号,同时在第1行之前插入两行文本,第一行内容为"How are you?",第二行内容为"How old are you?":

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost ~]# nl /etc/passwd | sed '1i \How are you?\nHow old are you?'
How are you?
How old are you?
1    root:x:0:0:root:/root:/bin/bash
2    bin:x:1:1:bin:/bin:/sbin/nologin
3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
4    adm:x:3:4:adm:/var/adm:/sbin/nologin
.....(后面省略).....
 
 
命令解释:
可使用\n以实现多行插入文本。

 

在/etc/passwd第2行之后追加文本"Drink tea?":

1
2
3
4
5
6
7
8
[root@localhost ~]# nl /etc/passwd | sed '2a \Drink tea?'
1    root:x:0:0:root:/root:/bin/bash
2    bin:x:1:1:bin:/bin:/sbin/nologin
Drink tea?
3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
4    adm:x:3:4:adm:/var/adm:/sbin/nologin
5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
.....(后面省略).....

 

删除/etc/passwd第2行至第5行内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost ~]# nl /etc/passwd | sed '2,5d'
1    root:x:0:0:root:/root:/bin/bash
6    sync:x:5:0:sync:/sbin:/bin/sync
7    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8    halt:x:7:0:halt:/sbin:/sbin/halt
9    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
1    0operator:x:11:0:operator:/root:/sbin/nologin
.....(后面省略).....
 
 
命令解释:
因为在模式空间中,第2行~第5行中每一行会被匹配到,而d命令会删除在模式空间中匹配到的行,
因此这几行不输出。

 

删除/etc/passwd中除了第一行之外的所有行:

1
2
[root@localhost ~]# nl /etc/passwd | sed '1!d'
1    root:x:0:0:root:/root:/bin/bash

 

把文本第一行之后的空白行删除:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
待处理的test文本内容如下:
[root@localhost ~]# cat test
aaaaaa
 
bbb
cc
d
e
[root@localhost ~]
[root@localhost ~]# sed '1{n;d}' test
aaaaaa
bbb
cc
d
e
[root@localhost ~]
 
 
命令解释:
因为地址匹配的是第一行,所以两个指令是针对第一行来进行处理的;当第一行读进来后,因为第
一行符合匹配条件,所以会对第一行执行处理命令,首先执行的是n命令,即用第二行覆盖第一
行,在此之前第一行会默认输出至屏幕,而后在模式空间中的第一行被文本中的第二行覆盖,接
着再执行d命令,即把模式空间中的第一行(即文本的第二行删除)。接着再读取文本的第三行,不满
足匹配条件,因此不执行命令并默认输出,接着读取文本的第四行......
 
注意:对某一行执行多次处理可用{}将处理命令command括起来,花括号内的每个命令之间用分号分
隔。

 

4.2. 以行为单位的替换与打印

 

将/etc/passwd第三行替换为文本"This is the third line.":

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# nl /etc/passwd | sed '3c \This is the third line.'
1    root:x:0:0:root:/root:/bin/bash
2    bin:x:1:1:bin:/bin:/sbin/nologin
This is the third line.
4    adm:x:3:4:adm:/var/adm:/sbin/nologin
5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6    sync:x:5:0:sync:/sbin:/bin/sync
7    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8    halt:x:7:0:halt:/sbin:/sbin/halt
.....(后面省略).....

 

使用编辑命令y实现对应转换字符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
待处理的test文本内容如下:
[root@localhost ~]# cat test
a
b
c
d
aa
abc
[root@localhost ~]
 
将字符a、b、c分别替换为x、y、z:
[root@localhost ~]# sed 'y/abc/xyz/' test
x
y
z
d
xx
xyz
[root@localhost ~]#
 
 
命令解释:
因为没有接地址,因此是匹配全局;

 

用sed显示/etc/passwd的行号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost ~]# sed '=' /etc/passwd
1
root:x:0:0:root:/root:/bin/bash
2
bin:x:1:1:bin:/bin:/sbin/nologin
3
daemon:x:2:2:daemon:/sbin:/sbin/nologin
4
adm:x:3:4:adm:/var/adm:/sbin/nologin
5
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6
sync:x:5:0:sync:/sbin:/bin/sync
.....(后面省略).....
 
 
命令解释:
每个行号占用一行,显示行号,再显示行的内容。

 

只读/etc/passwd的前10行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost ~]# sed '10q' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
 
 
命令解释:
如果使用sed -n '1,10p' /etc/passwd,那么当文本文件非常大甚至有几百万行时,根据sed工作流
程,它会处理每一行,即便我们需要的仅是显示前10行,这是非常浪费CPU资源的,因此可使用q命
令,指定sed处理完前10行即退出。

 

4.3. 数据的查找替换

 

搜索/etc/passwd中root用户对应的一行,将'bash'改为'blueshell',再输出该行:

1
2
[root@localhost ~]# sed -n '/^root/{s/bash/blueshell/;p}' /etc/passwd
root:x:0:0:root:/root:/bin/blueshell

如果替换好该行的bash为blueshell后就退出,则:

1
2
[root@localhost ~]# sed -n '/^root/{s/bash/blueshell/;p;q}' /etc/passwd
root:x:0:0:root:/root:/bin/blueshell

在两个数字之间添加':':

1
2
3
4
5
6
7
8
待处理的test文本内容如下:
[root@localhost ~]# cat test
123
321
添加':'
[root@localhost ~]# sed -r 's/([0-9])([0-9])([0-9])/\1:\2:\3/' test
1:2:3
3:2:1

 

只用sed命令完成对"ifconfig ens33"命令执行结果的处理,要求输出为网卡ens33的IP地址:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
先尝试匹配'inet'
[root@localhost ~]# ifconfig ens33 | sed -n '/inet/p' 
inet 10.10.10.140  netmask 255.255.255.0  broadcast 10.10.10.255
inet6 fe80::20c:29ff:fec8:ff4e  prefixlen 64  scopeid 0x20<link>
 
再过滤掉inet6这一行:
[root@localhost ~]# ifconfig ens33 | sed -n '/inet\>/p' 
inet 10.10.10.140  netmask 255.255.255.0  broadcast 10.10.10.255
或者:
[root@localhost ~]# ifconfig ens33 | sed -n '/inet\b/p' 
inet 10.10.10.140  netmask 255.255.255.0  broadcast 10.10.10.255
 
接着删除IP前面的部分:
[root@localhost ~]# ifconfig ens33 | sed -n '/inet\>/p' | sed 's/^.*inet //'
10.10.10.140  netmask 255.255.255.0  broadcast 10.10.10.255
 
再删除IP后面的部分,得到最终结果:
[root@localhost ~]# ifconfig ens33 | sed -n '/inet\>/p' | sed 's/^.*inet //' | sed 's/
 netmask.*$//'
10.10.10.140
 
 
命令解释:
使用sed对列进行处理时,通常使用搜索替换s/pattern/replaces/,常使用的替换标记是g;不过  
sed在对列的处理上不如awk

 

将/etc/passwd第1到第5行中shell为/bin/bash的用户的shell改为'/bin/greenshell',再输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost ~]# sed -n '1,5{s@/bin/bash@/bin/greenshell@;p}' /etc/passwd
root:x:0:0:root:/root:/bin/greenshell
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
或者:
[root@localhost ~]# sed -n '1,5{s/\/bin\/bash/\/bin\/greenshell/;p}' /etc/passwd
root:x:0:0:root:/root:/bin/greenshell
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
 
 
命令解释:
当分隔符出现在模式或替换文本中时,需要进行转义;或者使用其他的分隔符,例如:s@@@, s###,
 s%%%, ...

 

4.4. 高级命令的使用

(b)高级命令:
    n:覆盖读取匹配到的行的下一行至模式空间中;
    N:追加读取匹配到的行的下一行至模式空间中,并用\n连接两行;
    D:删除模式空间的第一行的内容,并在模式空间中继续执行编辑命令;
    P:打印模式空间的第一行的内容;
    h:hold, 将模式空间中的内容覆盖至保持空间中;
    H:Hold, 将模式空间中的内容追加至保持空间中;
    g:get, 将保持空间中的内容覆盖至模式空间中;
    G:Get, 将保持空间中的内容追加至模式空间中;
    x:exchange, 将模式空间中的内容与保持空间中的内容互换;
     
     
注意:
(1) sed保持空间(Hold Space):用于保存模式空间的内容;
(2) h, H, g, G, x这5个高级命令会使用到sed的保持空间;

 

把文本的前两行拼接成一行,中间用空格隔开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
待处理的test文本内容如下:
[root@localhost ~]# cat test
this is a
boy
c
d
e
 
拼接前两行,中间用空格隔开:
[root@localhost ~]# sed '1{N;s/\n/ /}' test      
this is a boy
c
d
e
 
自己理解:先读取第一行,遇见N,之后加载第二行的内容,默认的是用\n拼接,把\n删除就是一行了
命令解释:
处理时,把第一行读取进模式空间中,而第一行能够被匹配,因此针对第一行执行花括号内的操作
:先追加读取第二行至模式空间中,第一行与第二行用\n连接;接着执行搜索替换,将'\n'替换为
空格,这样就实现拼接了。接着读取文本的第三行至模式空间中,因为不被匹配,因此不执行编辑
命令,在非静默模式下会直接输出模式空间的内容,因此直接输出'c';接着读取第四行......
 
 

[root@localhost ~]# sed 'N;s/\n//' test
this is aboy
cd
e

       

如果出现空白行只保留一个空白行,即删除多余的空白行,行与行之间最多只能有一个空白行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
待处理的test文本内容如下:
[root@localhost ~]# cat test
a
b
c
d
[root@localhost ~]
 
删除多余的空白行:
[root@localhost ~]# sed '/^$/{N;/\n$/D}' test
a
b
c
d
 
 
自己理解:
    N:追加读取匹配到的行的下一行至模式空间中,并用\n连接两行;
    D:删除模式空间的第一行的内容,并在模式空间中继续执行编辑命令;
首先读取匹配空白行,然后N,读取下一行,如果下一行就是\n$就表示是空白行,把第一行删除
 
 
解决思路:
首先用/^$/去匹配空白行,针对被匹配到的空白行执行编辑命令;接着可用命令N追加下一行至匹配
到的空白行之后,且用\n连接,这时可根据模式空间中的第二行(在这里是\n之后的内容)是否为空
,去判断空白行是否只有一行;如果\n后为非空字符串(例如b),则说明模式空间中只有一个空白行
;如果\n为空,则不止一个空白行,此时模式空间为:[]\n[],[]代表空白行;这时可使用命令D删
除模式空间中的第一行的内容(在这里第一行的内容为[])。
 
用同样的思路解释如下命令的执行结果:
[root@localhost ~]# sed '/^$/{N;/\n$/d}' test
a
b
c
d

 

显示以下文本中'a'的上一行的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
待处理的test文本内容如下:
[root@localhost ~]# cat test
1
a
2
b
3
c
4
a
c
 
要求只显示a上一行的内容:
[root@localhost ~]# sed -n 'N;/a$/P' test
1
4
 
 
自己理解:首先读取第一行,把下一行加进来,如果下面一行有a,就用P打印上一行,再然后读取第三行,加载第四行,就这样一直匹配下面,知道结束
解决思路:
读取一行进模式空间后,先追加下一行进来,判断是否是以'\n a'结束,因此可用'a$'来作为追加下一行后的匹配条件;如果是以'\n a'结束,则打印上一行;如果不是以'\n a'结束,则使用静默模式不输出。
 
 
命令解释:
第一行读取进模式空间时,先追加文本第二行进来,两者在模式空间中以\n连接,接着看看模式空
间中的内容是否满足模式/a$/的匹配条件;因为匹配,所以输出上一行,而加上-n选项抑制默认输
出,因此只输出一个'1';接着开始读取下一行'2'进入模式空间中,接着追加下一行'b'进来,模式
空间中的内容为:2 \n b;因为不匹配,所以在静默模式下不输出模式空间中的内容;接着读取下一行进模式空间中,再追加一行,此时模式空间的内容为:3 \n c;......再读取、追加,模式空间的内容为:4 \n a;符合匹配,输出'4';读取下一行,不再追加,且不符合匹配,在静默模式下不输出
 
 
尝试其他方法:
[root@localhost ~]# sed 'N;/a$/P;D' test
1
4
c
 
 
 
分析:
处理时,先把第一行放进模式空间中,追加下一行,模式空间内容为:1 \n a,因此符合条件,打印模式空间中的第一行1;接着删除模式空间中的第一行1;然后追加读取下一行2,此时模式空间内容为a \n 2,不符合匹配条件,因此不打印模式空间第一行,而删除模式空间中的第一行内容;再追加,模式空间内容为:2 \n b;......当模式空间内容剩下:a \n c时,因为不符合匹配条件,不打印模式空间中的第一行,而删除模式空间中的第一行,最后模式空间只剩下c,因为不是静默模式,所以默认输出c,故有此结果。
 
 
尝试:
[root@localhost ~]# sed 'N;/a$/P;d' test
1
4
c
 
 
 
分析:
处理时,先把第一行放进模式空间中,追加下一行,模式空间内容为:1\na,因此符合条件,打印
模式空间中的第一行1;接着删除模式空间中的行;然后读取文本的下一行'2'进入模式空间,追加
一行'b',此时模式空间中的内容为:2\nb,不符合匹配条件/a$/,直接执行d命令删除模式空间中
匹配到的行(此时匹配条件为全局);......最后模式空间中只剩下'c',在不是静默模式的情况下默
认输出。
 
 
要想把刚才的结果的最后一行'c'删除掉,可尝试:
[root@localhost ~]# sed '$!N;/a$/P;D' test
1
4
符合要求;
 
[root@localhost ~]# sed '$!N;/a$/P;d' test
1
4
同样符合要求;
 
但若将test文本改为这样:
[root@localhost ~]# cat test
1
a
2
b
3
c
4
a
a
即把最后一行改为'a'
 
这时再次执行上述命令:
[root@localhost ~]# sed '$!N;/a$/P;d' test
1
4
a
符合要求;
 
[root@localhost ~]# sed '$!N;/a$/P;D' test
1
4
a
a
不符合要求;
 
 
分析:
当输出4时,模式空间内容为:a,因为此时本行'a'不是文本的最后一行,所以会追加文本的下一行
(文本最后一行)至模式空间中,此时模式空间内容变为:a\na,符合匹配条件,打印模式空间的上
一行,而后删除模式空间的第一行'a',此时模式空间只剩下'a',因为没有加-n选项所以默认输出
此时模式空间中剩下的内容'a'
 
 
命令解释:
很多情况下,N、P、D这三个命令都是可以结合使用的,P命令都是用在N命令之后、D命令之前的。
这三个命令结合起来可形成一个输入输出的循环,并且每次只打印一行:读入一行后,N命令继续读
下一行,P命令打印第一行,D命令删除第一行,执行完成后回到最开始重复该过程。

 

在文本的每一行之后都添加一行空白行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
待处理的test文本内容如下:
[root@localhost ~]# cat test
a
b
c
d
e
[root@localhost ~]
 
使用命令G添加空白行:
[root@localhost ~]# sed 'G' test
a
b
c
d
e
[root@localhost ~]
 
 
命令解释:
命令G是将保持空间中的内容追加至模式空间中,而保持空间中的内容为空白,在追加后原有模式空
间中的内容多了:\n [];其中[]表示空白行。

 

将文本全部换为空白行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
待处理的test文本内容如下:
[root@localhost ~]# cat test
a
b
c
d
e
[root@localhost ~]
 
使用命令G:
[root@localhost ~]sed 'g' test
[root@localhost ~]
 
 
命令解释:
命令g是将保持空间中的内容覆盖至模式空间中,而保持空间默认为空。

 

命令H、x的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
待处理的test文本内容如下:
[root@localhost ~]# cat test
a
b
c
d
e
[root@localhost ~]
 
执行H命令:
[root@localhost ~]# sed 'H;$x' test
a
b
c
d
a
b
c
d
e
[root@localhost ~]
 
 
命令解释:
命令H是将模式空间中的内容追加至保持空间中;在读取文本最后一行'e'进入模式空间后,先追加
至保持空间中,而后因为符合匹配条件(最后一行'$'),因此执行x命令,即将模式空间中的内容与
保持空间中的内容互换,而保持空间此时的内容为:[] \n a \n b \n c \n d \n e,因此得到以上
执行结果。

 

4.5. sed 保持空间-综合示例

spacer.gifwKioL1ilCgKBmpvlAAAsGQNDNe8360.png

 

1
2
3
使用逗号拼接行:
[root@localhost ~]# sed 'H;$!d;${x;s/^\n//;s/\n/,/g}' test
1,2,3,4

 

五、sed与vim,awk,grep的比较

 

总的来说,相对于vim这种强大的“交互式”文本编辑器而言,sed的优势在于可以重复对文本的行进行处理,通常在对很多匹配到的行执行多条编辑命令时,这种优势体现更为明显,而如果用vim进行“交互式”处理时,则相当耗费时间,并且操作简单重复且繁琐枯燥。

 

sed与awk,grep这三种工具作为Linux文本处理三剑客,各有各自的优势,谁也替代不了谁。只是相比较而言,sed与awk功能更加强大,已独立成一种语言。grep在实现过滤文本时效率要比其他工具高得多sed作为流编辑器在对文本进行处理时功能非常强大,默认不会修改原文件;sed虽然有过滤功能,但实现起来效率低不如grep;而sed在对列的处理能力上相比awk要差得多,awk也是一种文本处理语言,在Linux上的实现为gawk(GNU awk),它把文本看成数据库,将文本分成许多段,然后分别对这些段进行处理或格式化后输出,且不修改原文件;awk是报告生成器,可格式化生成文本,因此非常适于生成具有一定格式的报告文本。

 

grep, sed, awk这几个工具在生产环境中经常搭配使用,结合文本查找工具find,可实现快速查找、过滤、处理文本的功能。