sed:stream editor(流编辑器)的缩写是一种在线非交互式编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。
Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等
非交互式编辑器,一次处理一行内容。
支持正则表达式:与grep一样,sed在文件中查找模式时也可以使用正则表达式(RE)和各种元字符,用于查找和替换,以下是sed支持的元字符:
sed 默认会输出文件的每一行,无论这行的内容是否能匹配上匹配模式,参数p假如被匹配到的则会再输出一次
[root@localhost ~]# sed -r '' /etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 192.168.221.2
//p 是 sed 的内部命令,是 打印(输出) 的作用
[root@localhost ~]# sed -r 'p' /etc/resolv.conf
# Generated by NetworkManager
# Generated by NetworkManager
search localdomain
search localdomain
nameserver 192.168.221.2
nameserver 192.168.221.2
sed会自动打印文件的每一行,同时查找模式匹配的行,找到后执行后面的命令,默认是 p 打印(不加 -n 的情况下)
示例文件:
[root@localhost ~]# vim test.txt
MA Daggett, 341 King Road, Plymouth MA
Alice Ford, 22 East Broadway, Richmond VA
MA Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Ma Road, mA Falls PA
Eric Adams, 20 Post Road, Sudbury mA
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Ma Pkwy, Mountain View CA
Sal Carpenter, 73 MA Street, Boston MA
常用案例:
[root@localhost ~]# sed -r 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
[root@localhost ~]# sed -ri 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
// -r 打印查看,文件内容没有修改;-ri 文件内容被修改
[root@localhost ~]# sed -r 's/MA/ma/' test.txt
ma Daggett, 341 King Road, Plymouth MA
Alice Ford, 22 East Broadway, Richmond VA
ma Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Ma Road, mA Falls PA
Eric Adams, 20 Post Road, Sudbury mA
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston MA
2.2 搜索每一行,找到所有的MA字符,进行全局替换为ma
[root@localhost ~]# sed -r 's/MA/ma/g' test.txt
ma Daggett, 341 King Road, Plymouth ma
Alice Ford, 22 East Broadway, Richmond VA
ma Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Ma Road, mA Falls PA
Eric Adams, 20 Post Road, Sudbury mA
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston ma
[root@localhost ~]# sed -r 's/MA/ma/gi' test.txt
ma Daggett, 341 King Road, Plymouth ma
Alice Ford, 22 East Broadway, Richmond VA
ma Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 ma Road, ma Falls PA
Eric Adams, 20 Post Road, Sudbury ma
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston ma
[root@localhost ~]# sed -rn 's/MA/ma/' test.txt
给予sed多个命令的时候需要-e选项;指定多个匹配时,使用-e
[root@localhost ~]# sed -r -e 's/MA/ma/gi' -e 's/PA/pa/gi' test.txt
ma Daggett, 341 King Road, Plymouth ma
Alice Ford, 22 East Broadway, Richmond VA
ma Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 ma Road, ma Falls pa
Eric Adams, 20 Post Road, Sudbury ma
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston ma
-f<script文件>
或--file=<script文件>
以选项中指定的script文件来处理输入的文本文件
[root@localhost ~]# vim sed.sh
s/MA/ma/
s/PA/pa/
s/Ro/ro/
s/VA/va/
s/Br/br/
[root@localhost ~]# sed -f sed.sh test.txt
ma Daggett, 341 King road, Plymouth MA
Alice Ford, 22 East broadway, Richmond va
ma Thomas, 11345 Oak bridge road, Tulsa OK
Terry Kalkas, 402 Ma road, mA Falls pa
Eric Adams, 20 Post road, Sudbury mA
Hubert Sims, 328A brook road, Roanoke va
Amy Wilde, 334 Ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston MA
[root@localhost ~]# sed -f sed.sh test.txt >sed.txt
[root@localhost ~]# cat sed.txt
ma Daggett, 341 King road, Plymouth MA
Alice Ford, 22 East broadway, Richmond va
ma Thomas, 11345 Oak bridge road, Tulsa OK
Terry Kalkas, 402 Ma road, mA Falls pa
Eric Adams, 20 Post road, Sudbury mA
Hubert Sims, 328A brook road, Roanoke va
Amy Wilde, 334 Ma Pkwy, Mountain View CA
Sal Carpenter, 73 ma Street, Boston MA
[root@localhost ~]# head /etc/passwd > passwd.txt //生成测试文件
[root@localhost ~]# sed -r '1d' passwd.txt //d:表示删除--1d表示删除文件的第1行
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
....
[root@localhost ~]# sed -r '1,2d' passwd //删除文件的1-2行
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 -r 's#/sbin/nologin#/bin/sh#g' passwd.txt
//或者 sed -r 's/\/sbin\/nologin/\/bin\/sh/g' passwd.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/sh
daemon:x:2:2:daemon:/sbin:/bin/sh
adm:x:3:4:adm:/var/adm:/bin/sh
....
[root@localhost ~]# sed -r '2,$d' passwd.txt //删除第2行到最后一行
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# sed -r '/^root/d' passwd.txt //匹配到root开头的行,删除此行
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
....
[root@localhost ~]# sed -r '/nologin/d' passwd.txt //含有nologin的行都删除
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
tang:x:1000:1000:tang:/home/tang:/bin/bash
[root@localhost ~]# sed -r '/bash/,3d' passwd.txt //匹配到bash行删除,(匹配到bash行在第一行则)到此行的第3行删除
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
....
[root@localhost ~]# sed -r '/^root/,3d' passwd.txt //匹配到root开头行,一直删除到【匹配行之后的三行】
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
....
[root@localhost ~]# cat -n passwd.txt //查看的同时并打印行号
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
....
[root@localhost ~]# sed -r '1~2d' passwd.txt //删除奇数行,表示从第1行开始,每隔2行匹配一次
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
[root@localhost ~]# sed -r '0~2d' passwd.txt //删除偶数行,表示从第0行开始,每隔2行匹配一次
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
//在第2行前插入
[root@localhost ~]# sed -r '2i2222' passwd.txt
root:x:0:0:root:/root:/bin/bash
2222
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
....
[root@localhost ~]# sed -r '2i222222\
3333333\
4444444' passwd.txt
//或者 sed -r '2i11111111\naaaaaaaaaa\nbbbbbbbbb' passwd.txt
root:x:0:0:root:/root:/bin/bash
222222
3333333
4444444
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
....
//第二行修改成text
[root@localhost ~]# sed -r '2c\text' passwd.txt
root:x:0:0:root:/root:/bin/bash
text
daemon:x:2:2:daemon:/sbin:/sbin/nologin
....
[root@localhost ~]# sed -ri '3c\dameon:test' passwd.txt //修改
[root@localhost ~]# sed -ri 's/SELINUX=enabled/SELINUX=disabled/' /etc/sysconfig/selinux //替换
由于在使用 -i 参数时比较危险, 所以我们在使用i参数时在后面加上.bak就会产生一个备份的文件,以防后悔
[root@localhost ~]# sed -ri.bak 's/root/ROOT/gi' passwd.txt
sed如果在脚本中使用的话,不可避免的要调用变量,所以以下这种方式可以用来调用变量
[root@localhost ~]# vim seed.sh
#!/usr/bin/bash
test=hello
echo "$test world" | sed "s/$test/HELLO/"
[root@localhost ~]# bash seed.sh
HELLO world
[root@localhost ~]#
se_en=(SELINUX=enforcing)
[root@localhost ~]# se_ds=(SELINUX=disabled)
[root@localhost ~]# echo $se_en|sed "s/$se_en/$se_ds/"
[root@localhost ~]# cp /etc/ssh/ssh_config .
[root@localhost ~]# sed -ri '/^#/d' ssh_config
[root@localhost ~]# cat sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
[root@localhost ~]# sed -ri '/^$/d' sshd_config
[root@localhost ~]# cat sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
问题:为什么匹配的是$呢?
[root@localhost ~]# vim sshd_config
HostKey /etc/ssh/ssh_host_rsa_key$
$ #添加了几行空行
$
$
:set list #用set list就能看出,空行的结尾符就是$
[root@localhost ~]# sed -ri.bak 'd' sshd_config
[root@localhost ~]# cat sshd_config
//或者直接用echo > sshd_config
[root@localhost ~]# sed -r '2,5s/^/#/g' sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
#SyslogFacility AUTHPRIV
#AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
[root@localhost ~]# cp /etc/yum.repos.d/CentOS-Base.repo .
//添加注释
[root@localhost ~]# sed -r 's/^baseurl/#baseurl/g' CentOS-Base.repo
//取消注释(注意空格)
[root@localhost ~]# sed -r 's/^# CentOS-Base.repo/CentOS-Base.repo/g' CentOS-Base.repo
[root@localhost ~]# cat -n test.txt
1 # CentOS-Base.repo
2 CentOS-Base.repo
3
4
5 #
6 # The mirror system uses the connecting IP address of the client and the
7 # update status of each mirror to pick mirrors that are updated to and
8 # geographically close to the client. You should use this for CentOS updates
[root@localhost ~]# sed -r '/^[\t]/d' test.txt
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates