一、简介
sed命令是词组stream editor的缩写,其功能是利用语法/脚本对文本文件进行批量的编辑操作,比利用vim直接编辑文件要便捷许多。
语法格式如下:
sed [选项] [操作] 文件名
(1)常用选项
sed命令的常用选项如下表所示。
选项 | 含义 |
-n | 在屏幕上只显示经sed处理过的行 |
-e 脚本 | 使用指定脚本处理文件 |
-r或-E | 使用扩展正则表达式的语法(默认为基础正则表达式语法) |
-i | 直接修改文件内容,且不输出到屏幕 |
-f filename | 使用指定脚本文件处理输入的文本文件 |
-h | 显示帮助信息 |
(2)操作格式
sed命令中,操作需用单引号括起来,其书写格式如下:
'[n1 [,n2]] 动作'
其中的n1表示要操作的行号,n1,n2表示要操作的范围,即第n1行到第n2行。
(3)操作中的动作
sed命令中,对文本文件执行的动作包括以下6个:
- a:新增,a的后面接需要新增的字符,新增的内容将在当前行的下一行中显示
- c:替换,c的后面接需要替换字符,表示替换第n1到n2行之间的内容
- d:删除,表示删除第n1到n2行之间的内容,其后通常不接内容
- i:插入,i的后面接需要插入的字符,表示插入的内容将在当前行的上一行中显示
- p:打印,将选择的数据打印出来,通常与sed -n一起执行
- s:替换,直接替换文件中的内容,其后通常接一个正则表达式
二、实例演示:
以文件/etc/passwd为例,文件前10行内容如下:
[root@node1 ~]# head -n 10 /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
1、以行为单位进行新增/删除
(1)删除指定行内容
# 打印查看第1-6行内容
[root@node1 ~]# sed -n '1,6p' /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
# 删除第2-5行内容
[root@node1 ~]# sed '2,5d' /etc/passwd | head
root:x:0:0:root:/root:/bin/bash
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
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
注:该操作并没有修改文件内容,只是打印到屏幕上的内容少了4行。
(2)在指定行的下方新增内容
# 打印查看第1-3行内容
[root@node1 ~]# sed -n '1,3p' /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
# 在第2行下方新增内容
[root@node1 ~]# sed '2a 000123456' /etc/passwd | head -n 5
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
000123456
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
注:该操作也没有修改文件内容,只是打印到屏幕上的内容中,在第2行的下方新增了一行内容。
(3)在指定行上方增加内容
# 在第2-3行上方增加内容
[root@node1 ~]# sed '2,3i 66668888' /etc/passwd | head -n 5
root:x:0:0:root:/root:/bin/bash
66668888
bin:x:1:1:bin:/bin:/sbin/nologin
66668888
daemon:x:2:2:daemon:/sbin:/sbin/nologin
(4)替换指定的内容
# 打印查看第1行内容
[root@node1 ~]# sed -n '1p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
# 将第1行内容替换成0000
[root@node1 ~]# sed '1c 0000' /etc/passwd | head -n 3
0000
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
注:可以验证,上述所有操作均未修改文件内容,仅仅只是修改了显示内容而已。
2、部分内容的查找并替换
这里仍以/etc/passwd文件为例。
此类操作的命令格式类似如下,将文件中的所有old-str替换成new-str,要注意的是如果字符串中有特殊字符(比如斜杆/、点号.和左或右括号等)则还需要进行转义。
# 替换找到的第1个old-str
sed 's/old-str/new-str/'
# 替换所有old-str
sed 's/old-str/new-str/g'
(1)修改指定行中的特定字符串
# 打印查看第1行的内容
[root@node1 ~]# sed -n '1p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
# 将第1行中第1个root替换成zhangsan
[root@node1 ~]# sed '1s/root/zhangsan/' /etc/passwd | head -n 1
zhangsan:x:0:0:root:/root:/bin/bash
# 将第1行中的所有root替换成zhangsan
[root@node1 ~]# sed '1s/root/zhangsan/g' /etc/passwd | head -n 1
zhangsan:x:0:0:zhangsan:/zhangsan:/bin/bash
(2)修改文件中的所有特定字符串
# 打印查看前3行内容
[root@node1 ~]# head -n 3 /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
# 将所有/sbin/nologin替换成/bin/bash
[root@node1 ~]# sed 's/\/sbin\/nologin/\/bin\/bash/g' /etc/passwd | head -n 3
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/bash
daemon:x:2:2:daemon:/sbin:/bin/bash
注:这里的操作仍未修改文件内容,也只是对要显示的内容作了修改
最后,再举个例子,结合了正则表示式,从ifconfig命令中提取指定接口的IP地址。如下所示,要将enp4s3接口的IP地址218.0.0.44提取出来。
[root@node1 ~]# ifconfig enp4s3
enp4s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 218.0.0.44 netmask 255.255.255.224 broadcast 218.0.0.63
inet6 fe80::f816:3eff:fe81:f994 prefixlen 64 scopeid 0x20<link>
ether fa:16:3e:81:f9:94 txqueuelen 1000 (Ethernet)
RX packets 715880 bytes 1349823875 (1.2 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 442120 bytes 47554664 (45.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
为完成上述需求,利用sed、管道线和正则表达式,命令和结果如下所示。
[root@node1 ~]# ifconfig enp4s3 | grep inet | sed 's/^.*inet //g' | sed '2d' | sed 's/netmask.*$//g'
218.0.0.44
3、直接修改文件内容
利用sed的选项-i可以修改文件内容,在修改配置文件时经常需要用到,因这种操作是破坏性操作,因此建议要谨慎操作,最好先对文件做好备份。
下面以编辑/etc/ssh/sshd_conf配置文件为例,为安全起见,这里将该配置文件复制一份出来进行实验。
[root@node1 ~]# cp /etc/ssh/sshd_config sshd_config1
(1)替换指定内容
# 查找配置文件中所有与root有关的配置项,不包括注释
[root@node1 ~]# grep -i 'root' sshd_config1 | grep -v '^#'
PermitRootLogin no
# 配置允许root远程连接
[root@node1 ~]# sed -i 's/PermitRootLogin no/PermitRootLogin yes/g' sshd_config1
# 核实配置是否修改成功
[root@node1 ~]# grep -i 'root' sshd_config1 | grep -v '^#'
PermitRootLogin yes
(2)添加内容
# 查看有关port的配置行
[root@node1 ~]# grep -i 'port' sshd_config1 | grep -v '^#'
GatewayPorts no
# 在第1行插入监听端口为8022的行
[root@node1 ~]# sed -i '1i Port 8022' sshd_config1
# 查看第1行内容
[root@node1 ~]# sed -n '1p' sshd_config1
Port 8022
(3)删除指定内容
配置文件中通常包括了大量注释信息和空行,资深管理员有时会方便查看和配置,会将这些注释和空行删除,为满足这个需求,也可以用sed的删除功能完成。
# 删除所有以#开头的注释行
[root@node1 ~]# sed -i '/^#.*$/d' sshd_config1
# 删除所有空行
[root@node1 ~]# sed -i '/^$/d' sshd_config1