Linux sed命令详解
sed是一个“非交互式的”面向字符流的编辑器。能同时处理多个文件多行的内容,可以不对原文件改动,把整个文件输入到屏幕,可以把只匹配到模式的内容输入到屏幕上。还可以对原文件改动,但是不会再屏幕上返回结果。
语法
sed [options] ‘sed command’ filename(s)
sed [options] -f ‘sed scriptfile’ filename(s)
sed命令选项(option):
-n :只打印模式匹配的行
-e :直接在命令行模式上进行sed动作编辑,此为默认选项
-f :将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作
-r :支持扩展表达式
-i :直接修改文件内容
命令:
命令 | 说明 |
---|---|
d | 删除,删除选择的行 |
D | 删除模块的第一条 |
s | 替换指定字符 |
h | 拷贝模块内容到内存中的缓冲区 |
H | 追加模块内容到内存中的缓冲区 |
g | 获得内存缓冲区的内容,并代替当前模块中的文本 |
G | 获得内存缓冲区的内容,并追加到当前模块文本的后面 |
l | 列表不能打印字符的清单 |
n | 读取下一个输入行,用下一个命令处理新的行而不是第一个命令 |
N | 追加下一个输入行到模块后面并在二者之间嵌入一个新行,改变当前行号码 |
p | 打印模块的行 |
P | 打印模块的第一行 |
q | 退出sed |
b label | 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾 |
r file | 从file中读行 |
t label | if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支带到有标号的命令处,或者到脚本的末尾 |
T label | 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支带到有标号的命令处,或者到脚本的末尾 |
w file | 写并追加模块到file末尾 |
W file | 写并追加模块的第一行到file末尾 |
! | 表示后面的命令对所有没有选定的行发生作用 |
= | 打印当前行号 |
# | 把注释扩展到第一个换行符以前 |
sed替换标记
命令 | 说明 |
---|---|
g | 表示行内全面 |
p | 表示打印行 |
w | 表示吧行写入一个文件 |
x | 表示互换模块中的文本和缓冲区中的文本 |
y | 表示吧一个字符翻译为另外的字符(但是不用于正则表达式) |
\1 | 字符串匹配标记 |
& | 已匹配字符串标记 |
sed元字符集
命令 | 说明 |
---|---|
^ | 匹配行开始,如:/^sed/匹配所有已sed开头的行 |
$ | 匹配行结束,如:/sed$/匹配所有已sed结尾的行 |
. | 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d |
* | 匹配0个或多个字符,如:/*sed/匹配说有模板是一个或多个空格后紧sed的行 |
[ ] | 匹配一个指定范围内的字符,如:/[sS]ed/匹配sed和Sed |
[^] | 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行 |
(…) | 匹配字符串,保存匹配的字符,如:(love)able/\1rs,loveable被替换成lovers |
< | 匹配单词的开始,如:/<love/匹配包含以love开头的单词的行 |
> | 匹配单词的结束,如:/love>/匹配包含以love结尾的单词的行 |
x{m} | 重复字符x,m次,如:/0{5}/匹配包含5个0的行 |
x{m,} | 重复字符x,至少m次,如:/0{5,}/匹配至少有5个0的行 |
x{m,n} | 重复字符x,至少m次,不多于n次,如:/0{5,10}/匹配5~10个0的行 |
Sed各种事例:
测试文件为:
[root@localhost ~]# cat qq.txt
my cat's name is betty
This is your dog
my dog's name is frank
This is your fish
my fish's name is george
This is your goat
my goat's name is adam
事例1:
S命令:替换指定字符
sed ‘s/This/aaa/’ qq.txt
[root@localhost ~]# cat qq.txt
my cat's name is betty
This is your dog
my dog's name is frank
This is your fish
my fish's name is george
This is your goat
my goat's name is adam
[root@localhost ~]# sed 's/This/aaa/' qq.txt
my cat's name is betty
aaa is your dog //替换后,This替换为aaa
my dog's name is frank
aaa is your fish
my fish's name is george
aaa is your goat
my goat's name is adam
事例2:
-n选项和p命令一起使用表示只打印那些发生替换的行:
sed -n ‘s/This/aaa/p’ qq.txt
[root@localhost ~]# sed -n 's/This/aaa/p' qq.txt
aaa is your dog
aaa is your fish
aaa is your goat
事例3:
直接编辑文件选项-i,会匹配qq.txt文件中每一行的第一个aaa替换为this:
sed -i ‘s/This/this/’ qq.txt
[root@localhost ~]# sed -i 's/This/this/' qq.txt
[root@localhost ~]# cat qq.txt
my cat's name is betty
this is your dog
my dog's name is frank
this is your fish
my fish's name is george
this is your goat
my goat's name is adam
事例4:
打印文件中的第二行,第二行会打印两遍,sed默认会打印所有行。
[root@localhost ~]# sed '2p' qq.txt
my cat's name is betty
this is your dog
this is your dog
my dog's name is frank
this is your fish
my fish's name is george
this is your goat
my goat's name is adam
事例5:
使用-n选项表示只打印匹配的行
[root@localhost ~]# sed -n '2p' qq.txt
this is your dog
事例6:
打印文件的第一到第三行。
[root@localhost ~]# sed -n '1,3p' qq.txt
my cat's name is betty
this is your dog
my dog's name is frank
事例7:
表示打印文件中匹配dog字符的行。
[root@localhost ~]# sed -n '/dog/p' qq.txt
this is your dog
my dog's name is frank
事例8:
打印文件中从匹配adam的行到第四行,adam所处的行如果在第四行之后,则表示仅打印匹配adam的行。如果adam正好在第四行,则只打印这一行。
[root@localhost ~]# sed -n '/adam/,4p' qq.txt
my goat's name is adam
事例9:
打印从第一行开始匹配到第一次出现dog字符的行,dog字符行也打印。
[root@localhost ~]# sed -n '1,/dog/p' qq.txt
my cat's name is betty
this is your dog
事例10:
打印文件中第一行到第四行的内容,且打印行号,当用到sed不同的编辑命令时,用{},且不同编辑命令之间用分号隔开。
[root@localhost ~]# sed -n '1,4{=;p}' qq.txt
1
my cat's name is betty
2
this is your dog
3
my dog's name is frank
4
this is your fish
事例11:
用!表示对前面的匹配的模式取反。
[root@localhost ~]# sed -n '1,4!{=;p}' qq.txt
5
my fish's name is george
6
this is your goat
7
my goat's name is adam
事例12:
sed的匹配模式支持正则表达式
打印前5行
[root@localhost ~]# sed '5q' /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
打印匹配r有0个或者多个,后接一个t字符的行
[root@localhost ~]# sed -n '/r*t/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
rtkit:x:499:499:RealtimeKit:/proc:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL
打印匹配有r的行并且r后面跟任意字符
[root@localhost ~]# sed -n '/.r.*/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
打印o字符重复任意次的行
[root@localhost ~]# sed -n '/o*/p' /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
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
打印o字重复出现一次以上的行
[root@localhost ~]# sed -n '/o\{1,\}/p' /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
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
打印o字重复出现一次到三次之间以上 的行
[root@localhost ~]# sed -n '/o\{1,3\}/p' /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
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
事例13:
打印出以#开头的行,然后用!进行反选,则表示过滤掉以#开头的行,不会过滤掉空格。
[root@localhost ~]# sed -n '/^#/!p' /etc/ntp.conf
driftfile /var/lib/ntp/drift
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict -6 ::1
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst
includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
server ntp.ntsc.ac.cn iburst
事例14:
匹配以#开头的行,进行反取,则打印出非#开头的行,然后其结果在对空格开头的去反,表示过滤掉以#和空格开头的行。
[root@localhost ~]# sed -n '/^#/!{/^$/!p}' /etc/ntp.conf
driftfile /var/lib/ntp/drift
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict -6 ::1
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst
includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
server ntp.ntsc.ac.cn iburst
事例15:
删除匹配以#开头的行,删除匹配空格的行(sed支持对单个文件实现不同的操作,每个操作用-e参数)
[root@localhost ~]# sed -e '/^#/d' -e '/^$/d' /etc/ntp.conf
driftfile /var/lib/ntp/drift
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict -6 ::1
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst
includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
server ntp.ntsc.ac.cn iburst
事例16:
打印匹配adm的行到第六行
[root@localhost ~]# sed -n '/adm/,6p' /etc/passwd
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
事例17:
匹配dog字符的行,行首添加nihao这个字符。
[root@localhost ~]# sed '/dog/s/^/nihao/' qq.txt
my cat's name is betty
nihaothis is your dog
nihaomy dog's name is frank
this is your fish
my fish's name is george
this is your goat
my goat's name is adam
事例18:
匹配adam字符,在这个字符前面添加qq
[root@localhost ~]# sed 's/adam/qq &/' qq.txt
my cat's name is betty
this is your dog
my dog's name is frank
this is your fish
my fish's name is george
this is your goat
my goat's name is qq adam
事例19:
匹配adam字符,在这个字符后面添加qq
[root@localhost ~]# sed 's/adam/& qq/' qq.txt
my cat's name is betty
this is your dog
my dog's name is frank
this is your fish
my fish's name is george
this is your goat
my goat's name is adam qq
事例20:
Sed的删除操作是针对文件的行,如果想删除行中的某个字符,可以使用替换。
[root@localhost ~]# cat myfile //文件内容
sed command
#hellow world tail and tail
#hellow world tail and tail
#how are you End
i am fine End
thanks, and you End
sed command end
[root@localhost ~]# sed '/^#/!d' myfile //删除以非#开头的行,即显示以#开头的行
#hellow world tail and tail
#hellow world tail and tail
#how are you End
[root@localhost ~]# sed '2,4d' myfile //删除文件指定的行
sed command
i am fine End
thanks, and you End
sed command end
[root@localhost ~]# sed '/thanks/d' myfile //删除匹配thanks的行
sed command
#hellow world tail and tail
#hellow world tail and tail
#how are you End
i am fine End
sed command end
[root@localhost ~]# sed -i -e '/sed/d' -e '/^#/d' myfile //-i参数直接对文件进行操作,当需要删除多种不同模式的匹配时,可以使用-e参数
[root@localhost ~]# cat myfile
i am fine End
thanks, and you End
sed替换操作
[root@localhost ~]# cat test //源文件
anonymous_enable=YES
write_enable=YES
local_umask=022
xferlog_enable=YES
connect_from_port_20=YES
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
DEVICE="eth0"
BOOTPROTO="static"
HWADDR="00:0C:29:90:79:78"
ONBOOT="yes"
IPADDR=172.16.22.1
NETMASK=255.255.0.0
[root@localhost ~]# sed -i '/DEVICE/c\Ethernet' test //匹配DEVICE的行,替换成Ethernet这行
[root@localhost ~]# sed -i 's/static/dhcp/' test //把static替换成dhcp
[root@localhost ~]# sed -i '/IPADDR/s@22\.1@10.12@' test //匹配IPADDR的行,把22.1替换成10.12由于.号有特殊意义所有需要转义(/,@,#都是前面所说的地址定界符)
[root@localhost ~]# sed -i '/connect/s#YES#NO#' test //匹配connect的行,把YES替换成NO
[root@localhost ~]# sed -i 's/bin/tom/2g' test //把所有匹配到bin的行中第二次及第二次之后出现bin替换成tom
[root@localhost ~]# sed -i 's/daemon/jerry/2p' test //把所有匹配到bin的行中第二次出现的daemon替换成jerry,并在生产与匹配行同样的行
[root@localhost ~]# sed -i 's/adm/boss/2' test //把所有匹配到adm的行中仅仅只是第二次出现的adm替换成boss
[root@localhost ~]# sed -i '/root/{s/bash/nologin/;s/0/1/g}' test //匹配root的行,把bash替换成nologin,且把0替换成1
[root@localhost ~]# sed -i 's/root/(&)/g' test //把root用括号括起来,&表示引用前面匹配的字符
[root@localhost ~]# sed -i 's/BOOTPROPO/#BOOTPROTO/' test //匹配BOOTPROTO替换成#BOOTPROTO,在配置文件中一般用于注释某行
[root@localhost ~]# sed -i 's/NOBOOT/#&/' test //匹配ONBOOT的行的前面添加#号,在配置文件中也表示注释某行
[root@localhost ~]# sed -i 's/NOBOOT/s/#//' test //匹配ONBOOT的行,把#替换成空,即去掉#号,也一般用作去掉#注释
#-------------执行以上sed命令之后文件显示的内容-----------
[root@localhost ~]# cat test
anonymous_enable=YES
write_enable=YES
local_umask=022
xferlog_enable=YES
connect_from_port_20=NO
(root):x:1:1:(root):/(root):/bin/nologin
bin:x:1:1:tom:/tom:/stom/nologin
daemon:x:2:2:jerry:/sbin:/stom/nologin
daemon:x:2:2:jerry:/sbin:/stom/nologin
adm:x:3:4:boss:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
Ethernet
#BOOTPROTO="dhcp"
HWADDR="00:0C:29:90:79:78"
ONBOOT="yes"
IPADDR=172.16.10.12
NETMASK=255.255.0.0