13流编辑器sed

流编辑器sed

sed 是一个流式编辑器程序,

它读取输入流(可以是文件、标准输入)的每一行放进 模式空间(pattern space)

同时将此行行号通过sed行号计数器记录在内存中,

然后对模式空间中的行进行模式匹配,如果能匹配上则使用sed程序内部的命令进行处理,

处理结束后,从模式空间中输出(默认)出去,并清空模式空间,

随后再从输入流中读取下一行到模式空间中进行相同的操作,直到输入流中的所有行都处理完成。

sed 工作流程

【sed循环的工作过程】:

1. 读取输入流的一行到模式空间
2. 对模式空间中的内容进行匹配和处理
3. 自动输出模式空间内容
4. 清空模式空间内容
5. 读取输入流的下一行到模式空间
sed -ri.bak
sed -ric --follow-symlinks  

sed 语法格式

sed [OPTIONS] SCRIPT INPUT_STREAM
==> 
sed [OPTIONS] 'command' file(s)
sed [OPTIONS] -f scriptfile file(s)

sed 常用选项

-n, --quiet, --silent:取消默认输出,sed默认会输出所有文本内容,使用-n参数后只显示处理过的行

-e script, --expression=script:它告诉sed将下一个参数解释为一个sed指令,只有当命令行上给出多个sed指令时才需要使用-e选项

-f script-file, --file=script-file:指定保存了sed指令的文件

-i[SUFFIX], --in-place[=SUFFIX]:直接对内容进行修改,不加-i时默认只是预览,不会对文件做实际修改

-r, --regexp-extended:支持扩展元字符

注意& 符号在sed命令中代表上次匹配的结果

SCRIPT 是 sed 内部命令的集合,它包含行匹配以及要执行的命令。格式:ADDR1[,ADDR2]cmd_list

例如,要对第2行执行删除命令,其命令为sed 2d filename;只输出第4行到6行,其命令为sed -n 4,6p

定址表达式

sed 将输入流中的行读取到模式空间后,就需要对模式空间中的内容进行匹配,如果能匹配就能执行对应的命令,如果不能匹配就直接输出、清空模式空间并进入下一个 sed 循环读取下一行。

匹配的过程称为定址,定址表达式有多种,但总的来说,其格式为[ADDR1][,ADDR2] ,可以分为3种方式:

1. ADDR1和ADDR2都省略时,表示所有行都能被匹配上

2. 省略ADDR2时,表示只有被ADDR1表达式匹配上的行才符合条件

3. 不省略ADDR2时,是范围地址。表示从ADDR1匹配成功的行开始,到ADDR2匹配成功的行结束

无论是ADDR1还是ADDR2,都可以使用两种方式进行匹配:行号(即数字)正则表达式

1. number
指定一个行号,sed将只匹配该行。(需要注意,除非使用了"-s"或"-i"选项,sed将对所有输入文件的行连续计数)

2. first~step
表示从第first行开始,每隔step行就再取一次。也就是取行号满足first+(N*step) (其中N>=0)的行。因此,要选择所有奇数行,使用"1~2";要从第2行开始每隔5行取一次,使用"2~5";要从第10行开始每隔5行取一次,使用"10~5";而"50~0"则表示只取第50行

3. $
默认该符号匹配的是最后一个文件的最后一行,如果指定了"-i"或"-s",则匹配的是每个文件的最后一行。总之,"$"匹配的是每个输入流的最后一行

4. /regexp/
将选择能被正则表达式regexp匹配的所有行。如果regexp中自身包含了字符"/",则必须使用反斜线转义,即"\/"


5. \cregexpc
('c'可以使用其他任意单个字符替换。) 这和上一个定址表达式的作用是一样的,只不过是使用符号"c"替换了符号"/"。当regexp中包含"/"符号时,使用该定址表达式就无需对"/"使用反斜线"\"转义。但如果此时regexp中包含了"c"符号时,该符号需要使用"\"转义

6. 0,addr2

这种形式的地址对,默认第一个地址是匹配的,也就是匹配开关打开,直到找到匹配addr2的那行为止,匹配开关关闭。
大多数情况下,0,addr2和1, addr2是一样的,除非addr2匹配文件的第一行,在这种时候,0, addr2就在第一行就关闭了,而1, addr2会继续往下找匹配的行

Start out in "matched first address" state, until addr2 is found.  This is similar to 1,addr2, except that if addr2 matches the very first line of input the 0,addr2 form will be at the end of its range, whereas the 1,addr2 form will still be at the beginning of its range.  This works only when addr2 is a regular expression.

7. addr1,+N
匹配addr1和其后的N行

8. addr1,~N
匹配addr1和其后的行直到出现N的倍数行。倍数可为随意整数倍,只要N的倍数是最接近且大于addr1的即可

如"1,~3" 表示 addr1=1,N=3,匹配1-3行;"5,~4" 表示 addr1=5,N=4,匹配5-8行。
而 "1,+3" 匹配的是第1行和其后的3行,即1-4行。

注意:在定址表达式的后面加 ! 符号表示反转匹配的含义。也就是说,反向匹配 ==> 那些匹配的行将不被选择,而是不匹配的行被选择。

示例说明

测试文件的文件内容

# 文件内容,注:编号只是为了方便查看
[root@hadoop04 shell_sed]# cat -n test_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
     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
    10  operator:x:11:0:operator:/root:/sbin/nologin
    
[root@hadoop04 shell_sed]# cat -n test_shadow 
     1  root:$6$4KlcFsuc9xAZczx3$DlUn31VBk05.T4tjSUxhkLjhlKijm7T6RvOa7Az8Ni7kHyDW7fevTtHFFdA1BGFl5UehKdqEHDWnL22yadnLa.::0:99999:7:::
     2  bin:*:17834:0:99999:7:::
     3  daemon:*:17834:0:99999:7:::
     4  adm:*:17834:0:99999:7:::
     5  lp:*:17834:0:99999:7:::
     6  sync:*:17834:0:99999:7:::
     7  shutdown:*:17834:0:99999:7:::
     8  halt:*:17834:0:99999:7:::
     9  mail:*:17834:0:99999:7:::
    10  operator:*:17834:0:99999:7:::

1.【number】

# 静默模式下,打印第三行的内容
[root@hadoop04 shell_sed]# sed -n '3p' test_passwd 
daemon:x:2:2:daemon:/sbin:/sbin/nologin

# 打印第3~5行的内容
[root@hadoop04 shell_sed]# sed -n '3,5p' test_passwd 
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

# 打印第3~5行以外的内容
[root@hadoop04 shell_sed]# sed -n '3,5!p' test_passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/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

2.【first~step】

# 打印奇数行的内容:从第一行开始,每隔两行执行一次p(打印)
[root@hadoop04 shell_sed]# sed -n '1~2p' test_passwd 
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

3.【$】

# 打印输入的最后一行的内容
# 如果不是有-s选项,即默认情况下,多个文件被当做是一个连续的长文件流,$匹配的是【最后一个文件】的最后一行
[root@hadoop04 shell_sed]# sed -n '$p' test_passwd  test_shadow 
operator:*:17834:0:99999:7:::

# 如果使用-s选项,将每一个输入文件视为独立文件,而不是单个连续的长文件流。$匹配的是【每一个文件】的最后一行
[root@hadoop04 shell_sed]# sed -ns '$p' test_passwd  test_shadow 
operator:x:11:0:operator:/root:/sbin/nologin
operator:*:17834:0:99999:7:::

4.【/regexp/、\cregexpc】

# 打印以mail开头的行
[root@hadoop04 shell_sed]# sed -n '/^mail/p' test_passwd test_shadow 
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mail:*:17834:0:99999:7:::

==>等价于

[root@hadoop04 shell_sed]# sed -n '\c^mailcp' test_passwd test_shadow 
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mail:*:17834:0:99999:7:::


# 打印包含/bin的行,由于regexp中自身包含了字符"/",所以需要使用反斜线转义,即"\/"
[root@hadoop04 shell_sed]# sed -n '/\/bin/p' test_passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

# 打印以mail开头的行,此处用\a代替/,但是mail中也带有a,所以mail中的a需要进行转义,即"m\ail"
[root@hadoop04 shell_sed]# sed -n '\a^m\ailap' test_passwd test_shadow 
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mail:*:17834:0:99999:7:::

5.【0,addr2】

# 打印从第一行到以bin开头的行的内容(一般情况下,0,addr2和1, addr2匹配出来的结果是一样的)
[root@hadoop04 shell_sed]# sed -n '0,/^bin/p' test_passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

[root@hadoop04 shell_sed]# sed -n '1,/^bin/p' test_passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin


# 打印从第一行到以root开头的行的内容
[root@hadoop04 shell_sed]# sed -n '0,/^root/p' test_passwd
root:x:0:0:root:/root:/bin/bash

[root@hadoop04 shell_sed]# sed -n '1,/^root/p' test_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

【总结】
0, addr2 这种形式默认第一个地址是匹配的,然后直到addr2匹配为止。因此上述情况,只要看每一行(从第一行开始)是否匹配第二个地址addr2就可以了,因为第一行是匹配的,所以打印到第一行为止。

1, addr2 这种形式就是普通形式,先匹配第一个地址,第一行是匹配的,然后读入第二行,发现不匹配addr2,继续读,直到最后也没找到匹配,因此打印从第1行到最后一行之间的所有内容

6.【addr1,+N】

# 打印第三行及其后面的四行内容,即打印3-7行的内容
[root@hadoop04 shell_sed]# sed -n '3,+4p' test_passwd 
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

7.【addr1,~N】

# 匹配第5行和其后的行直到出现4的倍数行,最接近5且大于5的4的倍数只有8,即打印第5-8行的内容
[root@hadoop04 shell_sed]# sed -n '5,~4p' test_passwd 
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

# 匹配addr1和其后的行直到出现N的倍数行。倍数可为随意整数倍,只要N的倍数是最接近且大于addr1的即可

sed 命令

sed 命令告诉 sed 对指定行进行何种操作,包括打印、删除、修改等。

a:追加,向匹配行后面插入一行或多行内容,多行时除最后一行外,每行末尾需用“\”续行

i:插入,在匹配行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行

c:更改,用此符号后的新文本替换匹配行中的文本。多行时除最后一行外,每行末尾需用"\"续行

d:删除,删除匹配行的内容

p:打印,打印出匹配的内容,通常与-n选项一起用

n:读取下一行,并从下一条命令而不是第一条命令开始对其的处理

r:从文件中读取内容,追加到匹配行

w:用于将匹配内容写入到文件

!:对所选行以外的所有行应用命令

s:替换,替换掉匹配的内容

=:打印被匹配的行的行号

l:列出非打印字符

q:结束或退出 sed

================暂存缓冲区================

h:把模式空间里的内容复制到暂存缓冲区(覆盖)

H:把模式空间里的内容追加到暂存缓冲区

g:取出暂存缓冲区的内容,将其复制到模式空间,覆盖该处原有内容

G:取出暂存缓冲区的内容,将其复制到模式空间,追加在原有内容后面

x:交换暂存缓冲区与模式空间的内容  

================暂存缓冲区================


====================s替换====================
s 替换标志
g 在行内进行全局替换
i 忽略大小写
r 从文件中读
w 将行写入文件
y 将字符转换为另一字符(不支持正则表达式)
====================s替换====================

测试文件的文件内容

# 文件内容,注:编号只是为了方便查看
[root@hadoop04 shell_sed]# cat -n test_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
     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
    10  operator:x:11:0:operator:/root:/sbin/nologin

1.追加命令【a】

向文件中追加行

# 向第3行后面追加 hello,3表示行号
[root@hadoop04 shell_sed]# sed '3ahello' test_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
hello
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

# 向第3行后面追加多行内容,分别是hello、world、testing、interesting,每行末尾需用“\”续行
[root@hadoop04 shell_sed]# sed '3ahello\
> world\
> testing\
> interesting' test_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
hello
world
testing
interesting
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

# 向内容包含lp的行后面追加一行内容 hello,如果文件中有多行包括lp,则包含lp的每一行后面都会添加 hello
[root@hadoop04 shell_sed]# sed '/lp/ahello' test_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
hello
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

# 在最后一行追加 hello
[root@hadoop04 shell_sed]# sed '$ahello' test_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
hello 

2.插入命令【i】

# 向第3行前面插入 hello,3表示行号,相当于,原先的第3行内容变成了第4行
[root@hadoop04 shell_sed]# sed '3ihello' test_passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
hello
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


# 向第3行插入多行内容,分别是hello、world、testing、interesting,每行末尾需用“\”续行
[root@hadoop04 shell_sed]# sed '3ihello\
> world\
> testing\
> interesting' test_passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
hello
world
testing
interesting
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


# 向内容包含root的行前面插入一行内容 hello,如果文件中有多行包括root,则包含root的每一行后前面都会插入 hello
[root@hadoop04 shell_sed]# sed '/root/ihello' test_passwd
hello
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
hello
operator:x:11:0:operator:/root:/sbin/nologin


# 在最后一行前面插入一行内容 hello
[root@hadoop04 shell_sed]# sed '$ihello' test_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
hello
operator:x:11:0:operator:/root:/sbin/nologin 

3.修改命令【c】

更改文件中指定的行

# 将文件test_passwd的第3行内容修改为 hello,3表示行号
[root@hadoop04 shell_sed]# sed '3chello' test_passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
hello
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

# 将包含root的行内容修改为 hello,如果文件中有多行包括root,则包含root的每一行都会被修改成 hello
[root@hadoop04 shell_sed]# sed '/root/chello' test_passwd
hello
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
hello

# 将文件test_passwd的最后一行内容修改为 hello
[root@hadoop04 shell_sed]# sed '$chello' test_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
hello

4.删除命令【d】

删除文件中的行

# 删除第4行
[root@hadoop04 shell_sed]# sed '4d' test_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
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

# 从第1行开始删除,每隔2行就删掉一行,即删除奇数行
[root@hadoop04 shell_sed]# sed '1~2d' test_passwd 
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt
operator:x:11:0:operator:/root:/sbin/nologin

# 删除第1~2行
[root@hadoop04 shell_sed]# sed '1,2d' test_passwd 
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

# 删除1~2之外的所有行
[root@hadoop04 shell_sed]# sed '1,2!d' test_passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

# 删除最后1行
[root@hadoop04 shell_sed]# sed '$d' test_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

# 删除包含root的行
[root@hadoop04 shell_sed]# sed '/root/d' test_passwd 
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

# 删除从包含lp的行到最后1行
[root@hadoop04 shell_sed]# sed '/lp/,$d' test_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的行及其后面一行
[root@hadoop04 shell_sed]# sed '/lp/,+1d' test_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
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

# 删除空行
[root@hadoop04 shell_sed]# sed '/^$/d' test_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

# 删除匹配root或halt的行,-r表示sed支持使用正则的扩展元字符,/root|halt/表示匹配root或halt
[root@hadoop04 shell_sed]# sed -r '/root|halt/d' test_passwd 
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
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

# 删除不匹配root或halt的行,-r表示sed支持使用正则的扩展元字符,/root|halt/表示匹配root或halt,!表示取反
[root@hadoop04 shell_sed]# sed -r '/root|halt/!d' test_passwd 
root:x:0:0:root:/root:/bin/bash
halt:x:7:0:halt:/sbin:/sbin/halt
operator:x:11:0:operator:/root:/sbin/nologin

# 删除1~3行中,以bin开头的行,1,3表示匹配1~3行,{/^bin/d}表示删除匹配bin作为行首的行
[root@hadoop04 shell_sed]# sed '1,3{/^bin/d}' test_passwd 
root:x:0:0:root:/root:/bin/bash
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 -r '1~2d' /etc/passwd      // 删除所有奇数行 odd-numbered
# sed -r '0~2d' /etc/passwd      // 删除所有偶数行 even-numbered

5.打印命令【p】

打印文件中的行

# 默认操作就是打印输出
[root@hadoop04 shell_sed]# sed '' test_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

# 打印第1-3行的内容,加上默认的打印,就会出现1-3行被打印了两次
[root@hadoop04 shell_sed]# sed '1,3p' test_passwd 
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/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

# -n选项表示取消默认输出,sed默认会输出所有文本内容,使用-n参数后只显示处理过的行
[root@hadoop04 shell_sed]# sed -n '1,3p' test_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

6.获取下一行命令【n】

# 打印包含lp的下一行内容
[root@hadoop04 shell_sed]# sed -n '/lp/{n;p}' test_passwd 
sync:x:5:0:sync:/sbin:/bin/sync

# 删除包含lp的下一行内容
[root@hadoop04 shell_sed]# sed -r '/lp/{n;d}' test_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
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

# -n选项表示取消默认输出,/lp/表示匹配lp的行,{n;s/sbin/haha/;p}表示先获取匹配lp的行的下一行内容,s/sbin/haha/表示将该行中的sbin替换成haha,最后打印输出
[root@hadoop04 shell_sed]# sed -n '/lp/{n;s/sbin/haha/;p}' test_passwd 
sync:x:5:0:sync:/haha:/bin/sync

7.读文件命令【r】

从文件中读取内容,追加到匹配行

# 从文件/etc/hosts中读取内容,追加到第3行后面
[root@hadoop04 shell_sed]# sed '3r /etc/hosts' test_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
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.22.34.16 hadoop00
172.22.34.17 hadoop01
172.22.34.18 hadoop02
172.22.34.19 hadoop03
172.22.34.20 hadoop04
172.22.34.21 hadoop05
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

# 从文件/etc/hosts中读取内容,追加到包含3的行后面,注意3和/3/的区别
[root@hadoop04 shell_sed]# sed '/3/r /etc/hosts' test_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
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.22.34.16 hadoop00
172.22.34.17 hadoop01
172.22.34.18 hadoop02
172.22.34.19 hadoop03
172.22.34.20 hadoop04
172.22.34.21 hadoop05
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

8.写文件命令【w】

将匹配内容写入到文件

# 将文件test_passwd中的第5行~最后1行写入/tmp/sed_test.txt(以覆盖的形式)
# 如果/tmp/sed_test.txt文件不存在则创建,如果/tmp/sed_test.txt存在则覆盖之前的内容
[root@hadoop04 shell_sed]# sed -n '5,$w /tmp/sed_test.txt' test_passwd
[root@hadoop04 shell_sed]# cat /tmp/sed_test.txt
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

# 将文件test_passwd的第5行和最后1行内容写入/tmp/sed_test.txt
# -e的作用:提示sed将下一个参数解释为一个sed指令
[root@hadoop04 shell_sed]# sed -n -e '5w /tmp/sed_test.txt'  -e '$w /tmp/sed_test.txt' test_passwd
[root@hadoop04 shell_sed]# cat /tmp/sed_test.txt
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

9.替换命令【s】

替换文件中的内容

# 将文件中的root替换为mike,默认只替换匹配行的第一个root
[root@hadoop04 shell_sed]# sed 's/root/mike/' test_passwd 
mike: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:/mike:/sbin/nologin

# 将文件中所有的root替换为mike
[root@hadoop04 shell_sed]# sed 's/root/mike/g' test_passwd 
mike:x:0:0:mike:/mike:/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:/mike:/sbin/nologin

# 将文件中所有的ROOT(忽略大小写,即可以是root,Root等等)替换为mike,-i表示忽略大小写
[root@hadoop04 shell_sed]# sed 's/ROOT/mike/gi' test_passwd
mike:x:0:0:mike:/mike:/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:/mike:/sbin/nologin

# 将匹配行中第二个匹配的root替换为mike
[root@hadoop04 shell_sed]# sed 's/root/mike/2' test_passwd 
root:x:0:0:mike:/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

# 将文件中所有的root替换为mike,并将替换后的内容写入1.txt
[root@hadoop04 shell_sed]# sed 's/root/mike/gw 1.txt' test_passwd 
mike:x:0:0:mike:/mike:/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:/mike:/sbin/nologin
[root@hadoop04 shell_sed]# cat 1.txt 
mike:x:0:0:mike:/mike:/bin/bash
operator:x:11:0:operator:/mike:/sbin/nologin

# 在每行末尾添加YYY,-r表示sed支持使用正则的扩展元字符,(.*)代表一行的所有内容,&代表在查找串中匹配到的内容
[root@hadoop04 shell_sed]# sed -r 's/(.*)/&YYY/' test_passwd
root:x:0:0:root:/root:/bin/bashYYY
bin:x:1:1:bin:/bin:/sbin/nologinYYY
daemon:x:2:2:daemon:/sbin:/sbin/nologinYYY
adm:x:3:4:adm:/var/adm:/sbin/nologinYYY
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologinYYY
sync:x:5:0:sync:/sbin:/bin/syncYYY
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdownYYY
halt:x:7:0:halt:/sbin:/sbin/haltYYY
mail:x:8:12:mail:/var/spool/mail:/sbin/nologinYYY
operator:x:11:0:operator:/root:/sbin/nologinYYY

# 将每一行中所有的数字加上一个小括号   ([0-9])表示0-9的数字,&符号代表匹配的内容
[root@hadoop04 shell_sed]# sed 's/[0-9]/(&)/g' test_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):(1)(2):mail:/var/spool/mail:/sbin/nologin
operator:x:(1)(1):(0):operator:/root:/sbin/nologin

# 作用与上面相同,-r表示sed支持使用正则的扩展元字符,()表示分组匹配,\1代表匹配的内容
[root@hadoop04 shell_sed]# sed -r 's/([0-9])/(\1)/g' test_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):(1)(2):mail:/var/spool/mail:/sbin/nologin
operator:x:(1)(1):(0):operator:/root:/sbin/nologin

10.打印行号【=】

打印文件的行号

# 打印test_passwd文件所有行的行号
[root@hadoop04 shell_sed]# sed -n "=" test_passwd 
1
2
3
4
5
6
7
8
9
10

# 打印test_passwd文件最后一行的行号
[root@hadoop04 shell_sed]# sed -n "$=" test_passwd 
10

# 打印匹配root的行的行号
[root@hadoop04 shell_sed]# sed -n "/root/=" test_passwd 
1
10

# 打印匹配root的行的行号和内容
# sed -n "/error/{=;p}" xxx.log  可用于查看日志中有error的行及其内容
[root@hadoop04 shell_sed]# sed -n "/root/{=;p}" test_passwd 
1
root:x:0:0:root:/root:/bin/bash
10
operator:x:11:0:operator:/root:/sbin/nologin

11.退出命令【q】

# 遇到以bin开头的行,退出sed,也就要说不再继续后面的行处理
[root@hadoop04 shell_sed]# sed "/^bin/q" test_passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

12.列出非打印字符【l】

列出非打印字符

# 列出非打印字符,此处只有换行符
[root@hadoop04 shell_sed]# sed -n "/root/l" test_passwd
root:x:0:0:root:/root:/bin/bash$
operator:x:11:0:operator:/root:/sbin/nologin$

13.【h H g G x】

sed 暂存空间与模式空间

暂存空间中的内容默认是换行符(回车符)

[root@hadoop04 shell_sed]# sed -r 'g' test_passwd 










[root@hadoop04 shell_sed]# sed -r 'G' test_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

[root@hadoop04 shell_sed]# sed -r 'G;G' test_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 -r '1h;$G' /etc/hosts
# sed -r '1{h;d};$G' /etc/hosts
# sed -r '1h; 2,$g' /etc/hosts
# sed -r '1h; 2,3H; $G' /etc/hosts

# 第1行的内容:root:x:0:0:root:/root:/bin/bash
# 将第1行内容以覆盖的方式放入暂存空间,处理到最后一行时,将暂存空间中的内容追加到模式空间,作为最后一行内容输出
# 相当于把第一行复制到最后一行
[root@hadoop04 shell_sed]# sed -r '1h;$G' test_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
root:x:0:0:root:/root:/bin/bash


# 第1行的内容:root:x:0:0:root:/root:/bin/bash
# 将第1行内容以覆盖的方式放入暂存空间,并且删除模式空间中的第一行内容,处理到最后一行时,将暂存空间中的内容追加到模式空间,作为最后一行内容输出
# 相当于把第一行剪切到最后一行
[root@hadoop04 shell_sed]# sed -r '1{h;d};$G' test_passwd
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
root:x:0:0:root:/root:/bin/bash

# 第1行的内容:root:x:0:0:root:/root:/bin/bash
# 将第1行内容以覆盖的方式放入暂存空间,处理第2行到最后一行时,将暂存空间中的内容覆盖到模式空间,作为第2行到最后一行的每一行内容输出
# 相当于将所有行内容都改成第1行内容
[root@hadoop04 shell_sed]# sed -r '1h;2,$g' test_passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash

# 第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
# 将第1行内容以覆盖的方式放入暂存空间,第2、3行追加到模式空间,在原文的最后一行时,将暂存空间中的所有内容追加到最后
# 相当于将1-3行内容复制到最后3行
[root@hadoop04 shell_sed]# sed -r '1h;2,3H;$G' test_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
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

# 第4行的内容:adm:x:3:4:adm:/var/adm:/sbin/nologin
# 第5行的内容:adm:x:3:4:adm:/var/adm:/sbin/nologin
# 处理到第4行时,以覆盖的方式放入暂存空间;l
# 处理到第5行时,交换暂存空间和模式空间的内容,==》模式空间的内容变成了第4行的内容,暂存空间的内容变成了第5行的内容;
# 处理到第6行时,将暂存空间的内容追加到第6行后面
# 也就说,第4、5行是原先第4行的内容,第6行内容不变,第5行内容移动到了第7行
[root@hadoop04 shell_sed]# sed -r '4h; 5x; 6G' test_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
adm:x:3:4:adm:/var/adm:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
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

14.反向选择【!】

反向选择

# 删除第3行
[root@hadoop04 shell_sed]# sed -r '3d' test_passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/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

# 删除第3行以外的行,即只保留第3行
[root@hadoop04 shell_sed]# sed -r '3!d' test_passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin

15.多重编辑【; {}】

# 删除第1行到第3行,然后将Hemenway替换成Jones
# 使用;替代-e选项
# sed -r -e '1,3d' -e 's/Hemenway/Jones/' datafile
# sed -r '1,3d; s/Hemenway/Jones/' datafile

# 将第2行所有的WE替换成UPLOOKING,所有Gray替换成YYY
# 使用{}合并对相同匹配行的操作
# sed -r '2s/WE/UPLOOKING/g; 2s/Gray/YYY/g' datafile
# sed -r '2{s/WE/UPLOOKING/g; s/Gray/YYY/g}' datafile

sed 支持正则表达式

与 grep 一样, sed 在文件中查找模式时也可以使用正则表达式(RE)和各种元字符。正则表达式是括在斜杠间的模式,用于查找和替换,以下是 sed 支持的元字符:
1.基本元字符集 ^, $, ., *, [], [^], \< \>,\(\),\{\}
2.扩展元字符集 ?, +, { }, |, ( )  

使用扩展元字符的方式:
1.在扩展元字符前加反斜线 \
2.sed -r

注:sed 和 grep 不一样,不管是否找到指定的模式,它的退出状态都是 0

只有当命令存在语法错误时, sed 的退出状态才是非 0

sed 常见操作

删除配置文件中#号注释行

# 删除以0到多个空格或者tab开头,后跟#的注释行
sed -ri '/^[ \t]*#/d' file.conf

# 示例:
[root@hadoop04 shell_sed]# cat test_ops.txt 
yangoooo
     # lldsfhasjhjhsaf
/etc/ac/123
        # 3dsfh
[root@hadoop04 shell_sed]# sed -r '/^[ \t]*#/d' test_ops.txt
yangoooo
/etc/ac/123

删除配置文件中//号注释行

# 删除以0到多个空格或者tab开头,后跟//的注释行
sed -ri '\Y^[ \t]*//Yd' file.conf

# 示例:
[root@hadoop04 shell_sed]# cat test_ops.txt
yangoooo
     //lldsfhasjhjhsaf
/etc/ac/123
    //3dsfh
# 由于匹配的内容中包含/,所以需要使用其他分隔符,此处使用\#或者\Y先声明
[root@hadoop04 shell_sed]# sed -r '\#^[ \t]*//#d' test_ops.txt
yangoooo
/etc/ac/123
[root@hadoop04 shell_sed]# sed -r '\Y^[ \t]*//Yd' test_ops.txt
yangoooo
/etc/ac/123

删除无内容空行

# 删除无内容空行
# 无内容空行:1.回车符 2.多个空格 3.多个tab键
sed -ri '/^[ \t]*$/d' file.conf

# 示例:
[root@hadoop04 shell_sed]# cat test_ops.txt
yangoooo
     //lldsfhasjhjhsaf
# 1.回车符

/etc/ac/123
# 2.多个空格
                           
    //3dsfh
# 3.多个tab键
        
[root@hadoop04 shell_sed]# sed -r '/^[ \t]*$/d' test_ops.txt
yangoooo
     //lldsfhasjhjhsaf
/etc/ac/123
    //3dsfh

删除注释行及空行

# 先删除所有注释行,再删除所有空行
# sed -ri '/^[ \t]*#/d; /^[ \t]*$/d' /etc/vsftpd/vsftpd.conf

# 使用扩展元字符,逐行处理时,删除注释行或者空行
# sed -ri '/^[ \t]*#|^[ \t]*$/d' /etc/vsftpd/vsftpd.conf

# 作用同上
# sed -ri '/^[ \t]*($|#)/d' /etc/vsftpd/vsftpd.conf  

修改文件

// 在/etc/vsftpd/vsftpd.conf文件最后一行追加 chroot_local_user=YES
# sed -ri '$a\chroot_local_user=YES' /etc/vsftpd/vsftpd.conf  

// 将 SELINUX= 开头的行改成 SELINUX=disabled
# sed -ri '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config

// 将包含 UseDNS 的行改成 UseDNS no
# sed -ri '/UseDNS/cUseDNS no' /etc/ssh/sshd_config

// 将包含 GSSAPIAuthentication 的行改成 GSSAPIAuthentication no
# sed -ri '/GSSAPIAuthentication/cGSSAPIAuthentication no' /etc/ssh/sshd_config

给文件行添加注释

# sed -r '2,6s/^/#/' a.txt

# sed -r '2,6s/(.*)/#\1/' a.txt

# sed -r '2,6s/.*/#&/' a.txt &匹配前面查找的内容

# sed -r '3,$ s/^#*/#/' a.txt 将行首零个或多个#换成一个#

# sed -r '30,50s/^[ \t]*#*/#/' /etc/nginx.conf

# sed -r '2,8s/^[ \t#]*/#/' /etc/nginx.conf


# 示例:
[root@hadoop04 shell_sed]# sed -r '2,6s/^/#/' a.txt
111
##222
#333
##444
#555
#666
ccc
[root@hadoop04 shell_sed]# sed -r '2,6s/(.*)/#\1/' a.txt
111
##222
#333
##444
#555
#666
ccc
[root@hadoop04 shell_sed]# sed -r '2,6s/.*/#&/' a.txt
111
##222
#333
##444
#555
#666
ccc
[root@hadoop04 shell_sed]# sed -r '3,$ s/^#*/#/' a.txt
111
#222
#333
#444
#555
#666
#ccc

sed 中使用外部变量

# var1=11111
# sed -ri '3a$var1' /etc/hosts  ==> 错误的做法
# sed -ri "3a$var1" /etc/hosts
# sed -ri "$a$var1" /etc/hosts  ==> 错误的做法
# sed -ri '$a\'"$var1" /etc/hosts
# sed -ri 3a$var1 /etc/hosts
# sed -ri "\$a$var1" /etc/hosts


# 示例:
[root@hadoop04 shell_sed]# var1=11111

# 在第3行的下一行追加变量var1的内容
[root@hadoop04 shell_sed]# sed -r "3a$var1" test_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
11111
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

# 在第3行的下一行追加变量var1的内容
[root@hadoop04 shell_sed]# sed -r 3a$var1 test_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
11111
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


# 在最后一行追加变量var1的内容
[root@hadoop04 shell_sed]# sed -r '$a\'"$var1" test_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
11111

# 在最后一行追加变量var1的内容
[root@hadoop04 shell_sed]# sed -r "\$a$var1" test_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
11111

作业

[root@tianyun ~]# vim 12345.txt  
1 
2 
3 
4 
5
[root@tianyun ~]# sed -r '1!G; $!h; $!d' 12345.txt
5 
4 
3 
2 
1

1!G 第一行不执行G命令,从第二行开始执行

$!h 最后一行不执行h命令,从第二行开始执行

$!d 最后一行不删除

图中P代表Pattern Space,H代表Hold Space。绿色代表pattern space中的数据,蓝色代表hold space中的数据

猜你喜欢

转载自www.cnblogs.com/ElegantSmile/p/12190327.html
今日推荐