sed基本用法:
sed: Stream EDitor
行编辑器 (全屏编辑器: vi)
sed: 模式空间
默认不编辑原文件,仅对模式空间中的数据做处理;而后,处理结束后,将模式空间打印至屏幕;
sed [options] 'AddressCommand' file ...
-n: 静默模式,不再默认显示模式空间中的内容
-i: 直接修改原文件
-e SCRIPT -e SCRIPT:可以同时执行多个脚本
-f /PATH/TO/SED_SCRIPT
sed -f /path/to/scripts file
-r: 表示使用扩展正则表达式
Address:
1、StartLine,EndLine
比如1,100
$:最后一行
2、/RegExp/
/^root/
3、/pattern1/,/pattern2/
第一次被pattern1匹配到的行开始,至第一次被pattern2匹配到的行结束,这中间的所有行
4、LineNumber
指定的行
5、StartLine, +N
从startLine开始,向后的N行;
Command:
d: 删除符合条件的行;
p: 显示符合条件的行;
a string: 在指定的行后面追加新行,内容为string
:可以用于换行
[root@data-1-3 ~]# sed '1a ###
fushanhua' /etc/fstab
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
###
fushanhua
UUID=a502aad2-4118-48be-bf98-f1660bab1c1e /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@data-1-3 ~]# sed '1,3a ###
fushanhua' /etc/fstab
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
###
fushanhua
UUID=a502aad2-4118-48be-bf98-f1660bab1c1e /boot ext4 defaults 1 2
###
fushanhua
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
###
fushanhua
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
i string: 在指定的行前面添加新行,内容为string
r FILE: 将指定的文件的内容添加至符合条件的行处
[root@data-1-3 ~]# sed '1r /etc/issue' /etc/fstab
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
CentOS release 6.7 (Final)
Kernel
on an m
UUID=a502aad2-4118-48be-bf98-f1660bab1c1e /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@data-1-3 ~]# sed '1,3r /etc/issue' /etc/fstab
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
CentOS release 6.7 (Final)
Kernel
on an m
UUID=a502aad2-4118-48be-bf98-f1660bab1c1e /boot ext4 defaults 1 2
CentOS release 6.7 (Final)
Kernel
on an m
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
CentOS release 6.7 (Final)
Kernel
on an m
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@data-1-3 ~]# sed '$r /etc/issue' /etc/fstab
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
UUID=a502aad2-4118-48be-bf98-f1660bab1c1e /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
CentOS release 6.7 (Final)
Kernel
on an m
w FILE: 将地址指定的范围内的行另存至指定的文件中;
[root@data-1-3 ~]# sed '$w /tmp/zui.txt' /etc/fstab
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
UUID=a502aad2-4118-48be-bf98-f1660bab1c1e /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@data-1-3 ~]# cat /tmp/zui.txt
proc /proc proc defaults 0 0
s/pattern/string/修饰符: 查找并替换,默认只替换每行中第一次被模式匹配到的字符串
加修饰符
g: 全局替换
i: 忽略字符大小写
s///: s###, s@@@
(), 1, 2
l..e: like-->liker
love-->lover
like-->Like
love-->Love
&: 引用模式匹配整个串
[root@data-1-3 tmp]# sed 's#l..e#&r#g' zui.txt
hello ,liker
hi,my lover
[root@data-1-3 tmp]# sed 's#(l..e)#1r#g' zui.txt
hello ,liker
hi,my lover
[root@data-1-3 tmp]# sed 's#(l..e)#1
#g' zui.txt
hello ,like
hi,my love
[root@data-1-3 tmp]# sed 's#(l..e)#1.#g' zui.txt
hello ,like.
hi,my love.
[root@data-1-3 tmp]# sed 's#l(..e)#L1#g' zui.txt
hello ,Like
hi,my Love
sed练习:
1、删除/etc/grub.conf文件中行首的空白符;
sed -r 's@^[[:spapce:]]+@@g' /etc/grub.conf
2、替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5;
sed 's@(id:)[0-9](:initdefault:)@152@g' /etc/inittab
3、删除/etc/inittab文件中的空白行;
sed '/^$/d' /etc/inittab
4、删除/etc/inittab文件中开头的#号;
sed 's@^#@@g' /etc/inittab
5、删除某文件中开头的#号及后面的空白字符,但要求#号后面必须有空白字符;
sed -r 's@^#[[:space:]]+@@g' /etc/inittab
6、删除某文件中以空白字符后面跟#类的行中的开头的空白字符及#
sed -r 's@^[[:space:]]+#@@g' /etc/inittab
7、取出一个文件路径的目录名称;
echo "/etc/rc.d/" | sed -r 's@^(/.*/)[^/]+/?@1@g'
基名:
echo "/etc/rc.d/" | sed -r 's@^/.*/([^/]+)/?@1@g'
#abc
# hello world
# hi world
练习:
传递一个用户名参数给脚本,判断此用户的用户名跟其基本组的组名是否一致,并将结果显示出来。
练习例子:(/etc/fstab)
Address:
1、StartLine,EndLine
比如1,100
$:最后一行
[root@data-1-3 ~]# sed -n 1,3p /etc/fstab
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
UUID=a502aad2-4118-48be-bf98-f1660bab1c1e /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
[root@data-1-3 ~]# sed -n 1,3d /etc/fstab
[root@data-1-3 ~]# sed 1,3d /etc/fstab
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/^root/
[root@data-1-3 ~]# sed -r -n '/^#|^$/p' /etc/fstab
#
# /etc/fstab
# Created by anaconda on Tue May 31 07:30:11 2016
#
# 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
#
第一次被pattern1匹配到的行开始,至第一次被pattern2匹配到的行结束,这中间的所有行
[root@data-1-3 ~]# sed -n '/devpts/,/proc/p' /etc/fstab
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
[root@data-1-3 ~]# sed '/devpts/,/proc/d' /etc/fstab
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
UUID=a502aad2-4118-48be-bf98-f1660bab1c1e /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
指定的行
[root@data-1-3 ~]# sed -n '$p' /etc/fstab
proc /proc proc defaults 0 0
[root@data-1-3 ~]# sed -n '5p' /etc/fstab
devpts /dev/pts devpts gid=5,mode=620 0 0
从startLine开始,向后的N行;
[root@data-1-3 ~]# sed '2,+2p' /etc/fstab
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
UUID=a502aad2-4118-48be-bf98-f1660bab1c1e /boot ext4 defaults 1 2
UUID=a502aad2-4118-48be-bf98-f1660bab1c1e /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc
经典案例:
sed 取接口IP地址:
[fush@xm35 ~ 18:50:47]$ ifconfig eth0
eth0 Link encap:Ethernet HWaddr 90:B1:1C:47:A7:E8
inet addr:192.168.0.35 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::92b1:1cff:fe47:a7e8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1496 Metric:1
RX packets:5096955365 errors:0 dropped:104 overruns:0 frame:0
TX packets:5128482803 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2361903276011 (2.1 TiB) TX bytes:2114718154002 (1.9 TiB)
Interrupt:35
[fush@xm35 ~ 18:49:28]$ ifconfig eth0|sed -r -n 's#^.*addr:(.*) Bca.*$#1#g'
[fush@xm35 ~ 18:49:54]$ ifconfig eth0|sed -r -n 's#^.*addr:(.*) Bca.*$#1#gp'
192.168.0.35
[fush@xm35 ~ 18:49:59]$ ifconfig eth0|sed -r -n 's#^.*addr:(.*) Bca.*$#1#g'p
192.168.0.35
引用:
使用语法
sed命令的使用规则是这样的:
sed [option] 'command' input_file
其中option是可选的,常用的option有如下几种:
- -n 使用安静(silent)模式。在一般sed的用法中,所有来自stdin的内容一般都会被列出到屏幕上,但如果加上-n参数后,则只有经过sed特殊处理的那一行(或者动作)才会被列出来;
- -e 直接在指令列模式上进行 sed 的动作编辑;
- -f 直接将sed 的动作写在一个文件内, -f filename 则可以执行filename内的sed命令;
- -r 让sed命令支持扩展的正则表达式(默认是基础正则表达式);
- -i 直接修改读取的文件内容,而不是由屏幕输出。
常用的命令有以下几种:
- a : append即追加字符串, a 的后面跟上字符串s(多行字符串可以用
分隔),则会在当前选择的行的后面都加上字符串s;
- c : 取代/替换字符串,c 后面跟上字符串s(多行字符串可以用
分隔),则会将当前选中的行替换成字符串s;
- d: delete即删除,该命令会将当前选中的行删除;
- i : insert即插入字符串,i 后面跟上字符串s(多行字符串可以用
分隔),则会在当前选中的行的前面都插入字符串s;
- p: print即打印,该命令会打印当前选择的行到屏幕上;
- s: 替换,通常s命令的用法是这样的:1,2s/old/new/g,将old字符串替换成new字符串
命令示例
假设有一个本地文件test.txt,文件内容如下:
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-8%209%3A38%3A48.png?version=1&modificationDate=1465380070000&api=v2)
a命令
本例命令部分中的1表示第一行,同样的第二行写成2,第一行到第三行写成1,3
,用$
表示最后一行,比如2,$
表示第二行到最后一行中间所有的行(包含第二行和最后一行)。
本例的作用是在第一行之后增加字符串”add one”,从输出可以看到具体效果。
sed '1a add one' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-8%209%3A51%3A18.png?version=1&modificationDate=1465380070000&api=v2)
本例表示在第一行和最后一行所有的行后面都加上”add one”字符串,从输出可以看到效果。
sed '1,$a add one' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A25%3A28.png?version=1&modificationDate=1465629928000&api=v2)
本例表示在包含”first”字符串的行的后面加上字符串”add one”,从输出可以看到第一行包含first,所以第一行之后增加了”add one”
sed '/first/a add one' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A24%3A59.png?version=1&modificationDate=1465629899000&api=v2)
i命令
i命令使用方法和a命令一样的,只不过是在匹配的行的前面插入字符串,所以直接将上面a命令的示例的a替换成i即可
c命令
本例表示将最后一行替换成字符串”add one”,从输出可以看到效果。
sed '$c add one' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A28%3A14.png?version=1&modificationDate=1465630094000&api=v2)
本例将第四行到最后一行的内容替换成字符串”add one”。
sed '4,$c add one' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A28%3A44.png?version=1&modificationDate=1465630124000&api=v2)
本例将以ha开头,以day结尾的行替换成”replace line”。
sed '/^ha.*day$/c
eplace line' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A32%3A7.png?version=1&modificationDate=1465630327000&api=v2)
d命令
本例删除以ha开头,以day结尾的行。
sed '/^ha.*day$/d' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A33%3A39.png?version=1&modificationDate=1465630419000&api=v2)
本例删除第四行到最后一行中的内容。
sed '4,$d' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A34%3A18.png?version=1&modificationDate=1465630458000&api=v2)
p命令
本例在屏幕上打印第四行到最后一行的内容,p命令一般和-n选项一起使用。
sed -n '4,$p' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A37%3A29.png?version=1&modificationDate=1465630649000&api=v2)
本例打印以ha开始,以day结尾的行。
sed -n '/^ha.*day$/p' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A38%3A6.png?version=1&modificationDate=1465630686000&api=v2)
s命令
本例将文件中的所有line替换成text,最后的g是global的意思,也就是全局替换,如果不加g,则只会替换本行的第一个line。
sed 's/line/text/g' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A51%3A7.png?version=1&modificationDate=1465631467000&api=v2)
本例首先匹配以ha开始,以day结尾的行,本例中匹配到的行是”happy everyday”这样,然后再将该行中的happy替换成very happy。
sed '/^ha.*day$/s/happy/very happy/g' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A52%3A26.png?version=1&modificationDate=1465631547000&api=v2)
下面这个例子复杂一点,先分解一下。首先s命令的模式是s/old/new/g
这样的,所以本例的old部分即(.*)line$
,sed命令中使用()
包裹的内容表示正则表达式的第n部分,序号从1开始计算,本例中只有一个()
所以(.*)
表示正则表达式的第一部分,这部分匹配任意字符串,所以(.*)line$
匹配的就是以line结尾的任何行。然后将匹配到的行替换成正则表达式的第一部分(本例中相当于删除line部分),使用1
表示匹配到的第一部分,同样2
表示第二部分,3
表示第三部分,可以依次这样引用。
sed 's/(.*)is(.*)line/12/g' test.txt
![](http://wiki.haplat.net/download/attachments/9573683/image2016-6-11%2015%3A54%3A46.png?version=1&modificationDate=1465631686000&api=v2)