首页 > 技术文章 > linux之sed的常用操作

diaosir 2017-02-12 12:18 原文

Sed命令:

  sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出或者加上 -i 参数(此时处理结果不会发送值屏幕).

 

sed 命令格式

  sed [options] 'command' file

  sed [options] -f scriptfile file

sed 用法实例

 

 

1.匹配模式的其它正则用法

sed-n '/r*t/p'/etc/passwd#打印匹配r有0个或者多个,后接一个t字符的行

 

sed -n '/.*r.*/p'/etc/passwd#打印匹配有r的行并且r后面跟任意字符
sed -n '/^r.*/p'/etc/passwd#打印匹配以r开头的行并且r后面跟任意字符
sed -n '/r$/p' /etc/passwd#打印匹配以结尾的

sed -n '/o*/p'/etc/passwd#打印o字符重复任意次(含0),并没什么意义
sed -n '/o\{4\}/p'/etc/passwd#打印o字重复出现4次

sed -n '/o\{1,\}/p'/etc/passwd#打印o字重复出现一次以上

sed -n '/o\{1,3\}/p'/etc/passwd#打印o字重复出现一次到三次之间以上

 

2.替换操作: s命令

 

 1 root@localhost:/home/wee/Desktop/linux#>cat 11
 2 11
 3 22
 4 33
 5 root@localhost:/home/wee/Desktop/linux#>sed 's/11/newline1/' 11
 6 newline1
 7 22
 8 33
 9 root@localhost:/home/wee/Desktop/linux#>cat 11
10 11
11 22
12 33
13 root@localhost:/home/wee/Desktop/linux#>sed -i 's/11/newline1/' 11
14 root@localhost:/home/wee/Desktop/linux#>cat 11
15 newline1
16 22
17 33

 

想要替换每一行中的所有匹配,在最后加g,如果想从第N次匹处开始替换所有使用Ng,只替换第N处使用N

 1 wee@localhost:~/Desktop/linux$>cat 11
 2 11 11 11
 3 22
 4 33
 5 wee@localhost:~/Desktop/linux$>sed 's/11/secondmatch/' 11
 6 secondmatch 11 11
 7 22
 8 33
 9 wee@localhost:~/Desktop/linux$>sed 's/11/secondmatch/2' 11
10 11 secondmatch 11
11 22
12 33
13 wee@localhost:~/Desktop/linux$>sed 's/11/secondmatch/3' 11
14 11 11 secondmatch
15 22
16 33
17 wee@localhost:~/Desktop/linux$>sed 's/11/secondmatch/2g' 11
18 11 secondmatch secondmatch
19 22
20 33
21 wee@localhost:~/Desktop/linux$>sed 's/11/secondmatch/g' 11
22 secondmatch secondmatch secondmatch
23 22
24 33

如上只是把替换结果输出到了屏幕文件内容并未变化,如果要文件保存更改使用 -i

wee@localhost:~/Desktop/linux$>sed -i 's/11/newline/g' 11
wee@localhost:~/Desktop/linux$>cat 11
newline newline newline 
22
33

上述命令中字符"/ "在sed中作为定界符使用,也可以使用其它的定界符(":" "|"等)

1 wee@localhost:~/Desktop/linux$>sed 's:11:secondmatch:g' 11
2 secondmatch secondmatch secondmatch
3 22
4 33
5 wee@localhost:~/Desktop/linux$>sed 's|11|secondmatch|g' 11
6 secondmatch secondmatch secondmatch
7 22
8 33

定界符出现在样式内部时,需要进行转义,否则报错

 1 wee@localhost:~/Desktop/linux$>cat 33
 2 root:x:0:0:root:/root:/bin/bash
 3 bin:x:1:1:bin:/bin:/sbin/nologin
 4 daemon:x:2:2:daemon:/sbin:/sbin/nologin
 5 adm:x:3:4:adm:/var/adm:/sbin/nologin
 6 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
 7 sync:x:5:0:sync:/sbin:/bin/sync
 8 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
 9 halt:x:7:0:halt:/sbin:/sbin/halt
10 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
11 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
12 wee@localhost:~/Desktop/linux$>sed 's:/:\:g' 33 13 sed: -e expression #1, char 7: unterminated `s' command

14 wee@localhost:~/Desktop/linux$>sed 's:\/:r:g' 33 15 root:x:0:0:root:rroot:rbinrbash 16 bin:x:1:1:bin:rbin:rsbinrnologin 17 daemon:x:2:2:daemon:rsbin:rsbinrnologin 18 adm:x:3:4:adm:rvarradm:rsbinrnologin 19 lp:x:4:7:lp:rvarrspoolrlpd:rsbinrnologin 20 sync:x:5:0:sync:rsbin:rbinrsync 21 shutdown:x:6:0:shutdown:rsbin:rsbinrshutdown 22 halt:x:7:0:halt:rsbin:rsbinrhalt 23 mail:x:8:12:mail:rvarrspoolrmail:rsbinrnologin

有些时候一个文件中可能有大部分没有用的内容,我们只想提取或者替换有限行我们可以使用 -n和p的结合

 

 1 wee@localhost:~/Desktop/linux$>cat 44 
 2 no usey
 3 no use
 4 no use
 5 useful
 6 no use
 7 no usey
 8 no use
 9 no use
10 useful
11 no use
12 useful
13 useful
14 wee@localhost:~/Desktop/linux$>sed -n '/useful/p' 44 15 useful 16 useful 17 useful 18 useful
19 wee@localhost:~/Desktop/linux$>sed -n 's/useful/userfulline/p' 44 20 userfulline 21 userfulline 22 userfulline 23 userfulline
24 wee@localhost:~/Desktop/linux$>sed -i -n 's/useful/userfulline/p' 44 25 wee@localhost:~/Desktop/linux$>cat 44 26 userfulline 27 userfulline 28 userfulline 29 userfulline

 

 

有可能不想对文件进行任何替换操作,只想知道匹配某一字符串的行都在第几行,怎么办?使用 -n和=

 

1 wee@localhost:~/Desktop/linux$>cat 11
2 11 11 11
3 22
4 33
5 wee@localhost:~/Desktop/linux$>sed -n '/22/=' 11
6 2

 

打印指定行和行号(=和p用分号隔开)

 

1 wee@localhost:~/Desktop/linux$>sed -n '1,4{=;p}' 33
2 1
3 root:x:0:0:root:/root:/bin/bash
4 2
5 bin:x:1:1:bin:/bin:/sbin/nologin
6 3
7 daemon:x:2:2:daemon:/sbin:/sbin/nologin
8 4
9 adm:x:3:4:adm:/var/adm:/sbin/nologin

 

 

保留打印文件前N行,使用Nq

 

1 wee@localhost:~/Desktop/linux$>sed '2q' 11
2 11 11 11
3 22
4 wee@localhost:~/Desktop/linux$>sed '3q' 11
5 11 11 11
6 22
7 33

 

从匹配行处打印到第N行,使用-n /pattern/,Np

 

wee@localhost:~/Desktop/linux$>cat 33
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
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
wee@localhost:
~/Desktop/linux$>sed -n '/halt/,10p' 33 halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

 

从第N行处开始打印到匹配行处(第一次匹配)

 

1 wee@localhost:~/Desktop/linux$>sed -n '1,/33/p' 11
2 11 11 11
3 22
4 33

 

打印两次匹配之间所有行

 

 

 

 

 

 1 wee@localhost:~/Desktop/linux$>cat 22
 2 aa
 3 bb
 4 cc
 5 dd
 6 wee@localhost:~/Desktop/linux$>sed -n '/aa/,/cc/p' 22
 7 aa
 8 bb
 9 cc

 

打印匹配a有0个或者多个,后接一个t字符的行

1 wee@localhost:~/Desktop/linux$>cat 22
2 aamofsdntt
3 bb
4 cc
5 dd
6 
7 wee@localhost:~/Desktop/linux$>sed -n '/a*t/p' 22
8 aamofsdntt

 #引用http://www.tuicool.com/articles/3qa67v 的内容

 1 [root@jie1 ~]# sed -i '/DEVICE/c\Ethernet' test #匹配DEVICE的行,替换成Ethernet这行
 3 [root@jie1 ~]# sed -i 's/static/dhcp/' test     #把static替换成dhcp(/,@,#都是前面所说的地址定界符)
 5 [root@jie1 ~]# sed -i '/IPADDR/s@22\.1@10.12@' test #匹配IPADDR的行,把22.1替换成10.12由于.号有特殊意义所有需要转义
 7 [root@jie1 ~]# sed -i '/connect/s#YES#NO#' test #匹配connect的行,把YES替换成NO
 9 [root@jie1 ~]# sed -i 's/bin/tom/2g' test       #把所有匹配到bin的行中第二次及第二次之后出现bin替换成tom
11 [root@jie1 ~]# sed -i 's/daemon/jerry/2p' test  #把所有匹配到bin的行中第二次出现的daemon替换成jerry,并在生产与匹配行同样的行
13 [root@jie1 ~]# sed -i 's/adm/boss/2' test       #把所有匹配到adm的行中仅仅只是第二次出现的adm替换成boss
15 [root@jie1 ~]# sed -i '/root/{s/bash/nologin/;s/0/1/g}' test#匹配root的行,把bash替换成nologin,且把0替换成1
17 [root@jie1 ~]# sed -i 's/root/(&)/g' test                 #把root用括号括起来,&表示引用前面匹配的字符
19 [root@jie1 ~]# sed -i 's/BOOTPROTO/#BOOTPROTO/' test      #匹配BOOTPROTO替换成#BOOTPROTO,在配置文件中一般用于注释某行
21 [root@jie1 ~]# sed -i 's/ONBOOT/#&/' test                 #匹配ONBOOT的行的前面添加#号,在配置文件中也表示注释某行
23 [root@jie1 ~]# sed -i '/ONBOOT/s/#//' test                2#匹配ONBOOT的行,把#替换成空,即去掉#号,也一般用作去掉#注释

 

 

3.删除操作: d命令

 1.删除以某个字符开头的行

 1 wee@pc~$cat 11
 2 #11
 3 22
 4 #33
 5 44
 6 55
 7 66
 8 wee@pc~$sed '/^#/d' 11
 9 22
10 44
11 55
12 66

2.删除命令"d"前加"!"表示取反,例子为删除以非"#"开头的行。。。

1 wee@pc~$sed '/^#/!d' 11
2 #11
3 #33

3.删除第N行

 1 wee@pc~$cat 11
 2 #11
 3 22
 4 #33
 5 44
 6 55
 7 66
 8 wee@pc~$sed '/2/d' 11
 9 #11
10 #33
11 44
12 55
13 6

4.删除最后一行

1 wee@pc~$sed '$d' 11
2 #11
3 22
4 #33
5 44
6 55

5.从第n行删到第m行

1 wee@pc~$sed '1,5d' 11
2 66

6.删除匹配字符串的行

1 wee@pc~$sed '/3/d' 11
2 #11
3 22
4 44
5 55
6 66
7 wee@pc~$sed '/3/!d' 11
8 #33
9 wee@pc~$

7.同时定义多个条件用 "-e"

 1 wee@pc~$cat 11
 2 #11
 3 22
 4 #33
 5 44
 6 55
 7 66
 8 wee@pc~$sed -e '/11/d' -e '/44/d' 11
 9 22
10 #33
11 55
12 66
13 wee@pc~$

4.行插入操作(a:行后插入i:行前插入)

 

 1 [root@VM_41_84_centos ~]# sed '/22/a\insert line' 11
 2 #11
 3 22
 4 insert line
 5 #33
 6 44
 7 55
 8 66
 9 [root@VM_41_84_centos ~]# sed '/22/i\insert line' 11
10 #11
11 insert line
12 22
13 #33
14 44
15 55
16 66

 

推荐阅读