sed的常用命令解析
一.sed命令的工作原理
sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
二.常用参数
命令格式:
sed [option] 'sed command' filename
option常用选项:
-n: 只打印模式匹配的行
-e: 直接在命令行模式上进行sed的动作编辑,为默认选项
-f: 将sed的动作写在一个文件内,用-f执行filename执行filename内的sed动作
-r:支持扩展表达式
-i:直接修改文件内容
1.下面我们做一些小小的例子来使用以下sed
[root@server1 mnt]# cat passwd ##这是我们接下来要进行操作的内容
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
wxh:x:500:500::/home/wxh:/bin/bash
[root@server1 mnt]# sed -n '1p' passwd ##-n指定行数,1p表示第一行,这个语句便是打印第一行的意思
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
那如果要打印第2行到第5行呢?
[root@server1 mnt]# sed -n '2,5p' passwd ##打印第2-5行
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
如果我们我们不知道要找的内容在第几行,那就可以使用指定关键字的方法:
[root@server1 mnt]# sed -n '/wxh/p' passwd ##打印出含有“wxh“的行
wxh:x:500:500::/home/wxh:/bin/bash
也可以打印从所匹配行到指定行:
[root@server1 mnt]# sed -n '/sshd/,$p' passwd ##打印有sshd的行到最后一行
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
wxh:x:500:500::/home/wxh:/bin/bash
也可以指定匹配几个关键字:
[root@server1 mnt]# sed -n '/sbin/,/www/p' passwd ##打印有sbin或者有www的行
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
打印文件中第一行到第四行的内容,且打印行号,使用sed不同的编辑命令时,用{}括起来,且不同编辑命令之间用‘:‘分割:
[root@server1 mnt]# sed -n '1,4{=;p}' passwd
1
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
2
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
3
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
4
apache:x:48:48:Apache:/var/www:/sbin/nologin
用!表示对前面匹配的模式取反:
[root@server1 mnt]# sed -n '1,3!{=;p}' passwd
4
apache:x:48:48:Apache:/var/www:/sbin/nologin
5
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
6
wxh:x:500:500::/home/wxh:/bin/bash
2.使用正则表达时
^ 匹配以指定内容开头的行,用法格式:"^pattern"
$ 匹配以指定内容结尾的行,用法格式"pattern$"
^$ 空白行
[root@server1 mnt]# sed '1 q' passwd ##打印前一行
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
[root@server1 mnt]# sed '4 q' passwd ##打印前五行
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
[root@server1 mnt]# sed -n '/^#/!p' /etc/vsftpd/vsftpd.conf
##打印以#开头的行然后取反,表示取出所有不是以#开头的行,不会过滤掉空格
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=YES
##不会过滤掉空格
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
在上面的基础上过滤掉空白行:^$表示空白行
[root@server1 mnt]# sed -n '/^#/!{/^$/!p}' /etc/vsftpd/vsftpd.conf
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
sed可以实现对单个文件的不同操作
[root@server1 mnt]# sed -e '/^#/d' -e '/^$/d' /etc/vsftpd/vsftpd.conf
##删除以#开头的行和空白行
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
3.sed命令实现对文件内容的添加:(对源文件添加的话就用-i参数)
可实现功能:
【 匹配行的行首添加,添加在同行
匹配行的行中的某个字符后添加
匹配行的行尾添加字符
匹配行的前面行添加
匹配行的后面行添加
文件的行首添加一行
文件的 行尾添加一行 】
[root@server1 mnt]# sed '/book/s/^/but /' file ##在匹配到bok的行行首添加‘but ‘
hello world
tom is a cat
today is sunny
but this is a book
[root@server1 mnt]# sed 's/world/wa &/' file ##匹配有world的行,并在world前加上‘wa‘
hello wa world
tom is a cat
today is sunny
this is a book
[root@server1 mnt]# sed 's/world/& !/' file ##匹配有world,并在world后加上‘!‘
hello world !
tom is a cat
today is sunny
this is a book
[root@server1 mnt]# sed 's/^/Start /' file ##在每行的行首添加‘Start‘
Start hello world
Start tom is a cat
Start today is sunny
Start this is a book
[root@server1 mnt]# sed 's/$/ End/' file ##在每行的行尾添加‘End‘
hello world End
tom is a cat End
today is sunny End
this is a book End
[root@server1 mnt]# sed '1,3s/^/#/' file
##在一到三行的行首添加‘#‘,一般用于注释配置文件中某行
#hello world
#tom is a cat
#today is sunny
this is a book
[root@server1 mnt]# sed '/sunny/s/^/# /' file ##将匹配到sunny的行注释掉
hello world
tom is a cat
# today is sunny
this is a book
##上面的操作都只是改变输出,并不会修改配置文件
如果想要直接修改源文件需要加上-i参数:
[root@server1 mnt]# cat file; sed -i 's/$/ End/' file ;cat file
##该源文件的每行结尾加上‘ End‘
hello world
tom is a cat
today is sunny
this is a book
hello world End
tom is a cat End
today is sunny End
this is a book End
[root@server1 mnt]# sed -i 's/End/Wa/g' file; cat file ##将文件中的所有End替换成Wa
hello world Wa
tom is a cat Wa
today is sunny Wa
this is a book Wa
使用-i参数实现对文件内容的删除:
[root@server1 mnt]# cat file
#hello world Wa
#tom is a cat Wa
today is sunny Wa
this is a book Wa
[root@server1 mnt]# sed '/^#/d' file ##删除以#开头的行
today is sunny Wa
this is a book Wa
[root@server1 mnt]# sed '2d' file ##删除文件的指定行
#hello world Wa
today is sunny Wa
this is a book Wa
4.sed命令实现对文件内容的替换(/,@, #地址定界符)
[root@server1 mnt]# sed '/root/c\root:root:root:/bin/nologin' passwd
##将有‘root‘的那行替换成‘root:root:root:/bin/nologin‘,如果需要对源文件进行修改在sed 后面加上-i参数即可
root:root:root:/bin/nologin
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
[root@server1 mnt]# sed 's/sbin/westos/' passwd ##全文替换,将sbin全部替换为westos
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/westos/nologin
daemon:x:2:2:daemon:/westos:/sbin/nologin
adm:x:3:4:adm:/var/adm:/westos/nologin
lp:x:4:7:lp:/var/spool/lpd:/westos/nologin
sync:x:5:0:sync:/westos:/bin/sync
shutdown:x:6:0:shutdown:/westos:/sbin/shutdown
[root@server1 mnt]# sed '/adm/s/nologin/login/' passwd ##匹配adm的行,将nologin换成login
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/login
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@server1 mnt]# sed '/root/{s/bash/nologin/;s/0/1/g}' passwd
##将匹配到root的行的bash换成nologin,这行所有的0换成1
root:x:1:1:root:/root:/bin/nologin
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
[root@server1 mnt]# sed 's/root/#&/' passwd ##匹配root的行加上#,在配置文件中也表示注释某行
#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
[root@server1 mnt]# cat file;sed '/hello/s/#//' file
##将含有hello的行的#替换为空,用于在配置文件取消注释
#hello world Wa
#tom is a cat Wa
today is sunny Wa
this is a book Wa
hello world Wa
#tom is a cat Wa
today is sunny Wa
this is a book Wa