赞
踩
使用 sed 命令,我们可以对文本内容进行逐行处理。
命令格式:
sed [OPTION]... {script} [input-file]
* script 用于指定需要匹配内容的地址及命令
常用选项:
-n 不打印模式空间内容
-i 直接编辑文件
-i.back 编辑文件前,备份文件,备份文件的名称是在原文件名后面加 .back
-r 或 -E 表示使用扩展正则表达式
地址格式:
单行:
n 表示 n 行
$ 表示最后一行
/pattern/ 匹配到的行,可能是多个行
地址范围
n,m 从 n 行到 m 行
n,+m 从 n 行到 n+m 行
/pat1/,/pat2/ 从匹配到 pat1 的行开始,到匹配到 pat2 的行结束
n,/pat 从 n 行到匹配到 pat 的行
命令:
p 打印所有内容,匹配到的以及原文内容
Ip 忽略大小写输出
d 删除匹配到的行
a 在匹配到的行后插入
i 在匹配到的行前面插入
c 替匹配到的行的内容
s/pattern/string/修饰符 查找替换,支持使用其它分隔符,可以是其它形式:s@@@,s###
替换修饰符:
g 行内全局替换
p 显示替换成功的行
I,i 忽略大小写
打印出第一行(p 表示打印)
[root@CentOS8Test ~]# sed "1p" /etc/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
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
......
......
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
user:x:1000:1000:User:/home/user:/bin/bash
apache:x:977:975::/home/apache:/sbin/nologin
* 但结果却显示了很多行,貌似整个文件内容都显示了,但我们看第一行和第二行,发现是一样的,也就是说,第一行显示了两遍;
sed 在每处理一行时,都会把当前处理的行存储在临时缓冲区中,称为模式空间(Pattern Space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。所以当我们只打印第一行的时候,它默认会将模式空间的内容再次输出,所以就会出现上面的情况;
此时我们添加 -n 选项, 不打印模式空间的内容:
[root@CentOS8Test ~]# sed -n "1p" /etc/passwd
root:x:0:0:root:/root:/bin/bash
我们可以使用 $p 来表示最后一行
[root@CentOS8Test ~]# sed -n '$p' /etc/passwd
apache:x:977:975::/home/apache:/sbin/nologin
我们也可以指定一段(行数)
创建一个测试文件:
[root@CentOS8Test ~]# seq 1 10 > test
[root@CentOS8Test ~]# cat test
1
2
3
4
5
6
7
8
9
10
匹配 1 到 3行
[root@CentOS8Test ~]# sed -n '1,3p' test
1
2
3
* 前面 1 是开始行,后面 3 是结束行;
我们也可以通过 + 的方式,以开始行加上一个数,来表示结束行;
[root@CentOS8Test ~]# sed -n '3,+4p' test
3
4
5
6
7
在匹配一段地址的时候,也可以使用 $p 来指定最后一行
[root@CentOS8Test ~]# sed -n '3,$p' test
3
4
5
6
7
8
9
10
打印匹配包含 root 的行(类似 grep 的匹配)
[root@CentOS8Test ~]# sed -n '/root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@CentOS8Test ~]# grep 'root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
我们也可以用匹配条件作为结束行,如,从第二行开始,到包含 root 的行结束:
[root@node1 ~]# sed -n '2,/root/p' /etc/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
我们也可以条件匹配来指定起始位置,如,从第一个匹配到 nologin 的行开始,直到匹配到 bash 的行结束
[root@node1 ~]# sed -n '/nologin/,/bash/p' /etc/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 games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin chrony:x:998:996::/var/lib/chrony:/sbin/nologin it:x:1000:1000:it:/home/it:/bin/bash
* 如果后面还存在 nologin 个 bash 的行,将会继续匹配
匹配以 /dev/sd 开头的设备:
[root@CentOS8Test ~]# sed -n '/^\/dev\/sd/p' /etc/passwd
[root@CentOS8Test ~]# df | sed -n '/^\/dev\/sd/p'
/dev/sda2 999320 129976 800532 14% /boot
/dev/sda1 613184 6768 606416 2% /boot/efi
因为我们要匹配的内容本身包含 / 所以我们需要转义;
通过 -i 选项直接编辑文件
[root@CentOS8Test ~]# sed -i '2d' test
[root@CentOS8Test ~]# cat test
1
3
4
5
6
7
8
9
10
我们可以在 i 后面加一个后缀,在编辑前备份文件:
[root@CentOS8Test ~]# sed -i.back '4d' test [root@CentOS8Test ~]# cat test 1 3 4 6 7 8 9 10 [root@CentOS8Test ~]# cat test.back 1 3 4 5 6 7 8 9 10
* 使用**. + 后缀**,这个只是为了方便识别,你也可以直接加后缀,不用 . ;
在匹配到的行前面插入
[root@node1 ~]# cat test 1 3 4 6 7 8 9 10 [root@node1 ~]# sed -i '/4/a\5' test [root@node1 ~]# cat test 1 3 4 5 6 7 8 9 10
在匹配到的行前面插入
[root@node1 ~]# sed -i '/3/i\2' test
[root@node1 ~]# cat test
1
2
3
4
5
6
7
8
9
10
替换匹配到的行
[root@node1 ~]# sed -i '/5/c\a' test
[root@node1 ~]# cat test
1
2
3
4
a
6
7
8
9
10
搜索替换
[root@node1 ~]# sed -i 's/a/5/g' test
[root@node1 ~]# cat test
1
2
3
4
5
6
7
8
9
10
我们可以使用 & 表示搜索到的字符
[root@node1 ~]# sed -i 's/5/&8/g' test
[root@node1 ~]# cat test
1
2
3
4
58
6
7
8
9
10
搜索替换并打印(不改变原文件)
[root@node1 ~]# sed -n 's/58/&5/p' test
585
通过 -e 选项,进行多条件匹配并操作
[root@node1 ~]# sed -n -e 's/58/5/p' -e 's/10/110/p' test
5
110
[root@node1 ~]# sed -i -e 's/58/5/g' -e 's/10/110/g' test
[root@node1 ~]# cat test
1
2
3
4
5
6
7
8
9
110
输入基数行和偶数行
[root@node1 ~]# sed -n '1~2p' test
1
3
5
7
9
[root@node1 ~]# sed -n '2~2p' test
2
4
6
8
110
在所有非注释行前面加 # 号
[root@CentOS8Test ~]# sed -rn "s/^[^#](.*)/#\1/p" /etc/fstab
#dev/mapper/cl-root / xfs defaults 0 0
#UID=9338b507-f6bb-49d6-8b9b-a3cbfc5bab52 /boot ext4 defaults 1 2
#UID=F949-8982 /boot/efi vfat umask=0077,shortname=winnt 0 2
#dev/mapper/cl-home /home xfs defaults 0 0
#dev/mapper/cl-swap swap swap defaults 0 0
获取分区的利用率:
[root@CentOS8Test ~]# df | sed -nr '/^\/dev\/sd/s# .* ([0-9]+)%.*# \1#p'
/dev/sda2 14
/dev/sda1 2
[root@CentOS8Test ~]# df | sed -nr '/^\/dev\/sd/s# .* ([0-9]+%).*# \1#p'
/dev/sda2 14%
/dev/sda1 2%
使用 sed 更改 selinux 配置
[root@nginx ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
[root@nginx ~]# cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of these three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
或通过:
[root@node1 ~]# cat /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing # SELINUXTYPE= can take one of three values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted [root@node1 ~]# sed -i '/^SELINUX=/c\SELINUX=disabled' /etc/selinux/config [root@node1 ~]# cat /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled # SELINUXTYPE= can take one of three values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted
利用sed 取出ifconfig命令中本机的IPv4地址
it@testsvr:~$ ifconfig | sed -rn 's/(.*inet )(([0-9]{1,3}\.?){4})(.*)/\2/p'
10.10.10.105
127.0.0.1
删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符
[root@CentOS8Test ~]# sed -r '/^#[[:blank:]].*/s/^#//' /etc/fstab # /etc/fstab Created by anaconda on Sun Sep 29 13:22:31 2019 # Accessible filesystems, by reference, are maintained under '/dev/disk/'. See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info. # After editing this file, run 'systemctl daemon-reload' to update systemd units generated from this file. # /dev/mapper/cl-root / xfs defaults 0 0 UUID=9338b507-f6bb-49d6-8b9b-a3cbfc5bab52 /boot ext4 defaults 1 2 UUID=F949-8982 /boot/efi vfat umask=0077,shortname=winnt 0 2 /dev/mapper/cl-home /home xfs defaults 0 0 /dev/mapper/cl-swap swap swap defaults 0 0
我们可以再次进行筛选,使结果更加美观:
[root@CentOS8Test ~]# sed -r '/^#[[:blank:]].*/s/^#[[:blank:]]//' /etc/fstab | sed /^#/d | sed /^$/d
/etc/fstab
Created by anaconda on Sun Sep 29 13:22:31 2019
Accessible filesystems, by reference, are maintained under '/dev/disk/'.
See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
After editing this file, run 'systemctl daemon-reload' to update systemd
units generated from this file.
/dev/mapper/cl-root / xfs defaults 0 0
UUID=9338b507-f6bb-49d6-8b9b-a3cbfc5bab52 /boot ext4 defaults 1 2
UUID=F949-8982 /boot/efi vfat umask=0077,shortname=winnt 0 2
/dev/mapper/cl-home /home xfs defaults 0 0
/dev/mapper/cl-swap swap swap defaults 0 0
处理/etc/fstab路径,使用sed命令取出其目录名和基名
[root@CentOS8Test ~]# echo /etc/fstab | sed -rn 's#(.*)/([^/].*)#\1#p'
/etc
[root@CentOS8Test ~]# echo /etc/fstab | sed -rn 's#(.*)/([^/].*)#\2#p'
fstab
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。