Stream EDitor, 行编辑器
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等
用法:
sed[option]... ‘script‘ inputfile...
常用选项:
-n:不输出模式空间内容到屏幕,即不自动打印
-e: 多点编辑
-f:/PATH/SCRIPT_FILE:从指定文件中读取编辑脚本
-r: 支持使用扩展正则表达式
-i: 原处编辑
script:‘地址命令‘
地址定界:
(1) 不给地址:对全文进行处理
(2) 单地址:
#: 指定的行
/pattern/:被此处模式所能够匹配到的每一行
(3) 地址范围:
#,# :从第几行到第几行
#,+# :以第几行为基础,向上或下显示到第几行
/pat1/,/pat2/:表示从pat1到pat的行
#,/pat1/
(4) ~:步进
1~2 奇数行
2~2 偶数行
编辑命令:
d: 删除模式空间匹配的行
p: 显示模式空间中的内容
a [\]text:在指定行后面追加文本
支持使用\n实现多行追加
i[\]text:在行前面插入文本
c [\]text:替换
w /path/somefile: 保存模式匹配的行至指定文件
r /path/somefile:读取指定文件的文本至模式空间中
匹配到的行后
=: 为模式空间中的行打印行号
!:模式空间中匹配行取反处理
s///:查找替换,支持使用其它分隔符,[email protected]@@,s###
替换标记:
g: 行内全局替换
p: 显示替换成功的行
w /PATH/TO/SOMEFILE:将替换成功的行保存至文件中
例子:
1、打印第三行;
[[email protected]~]# sed -n "3p" /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
2、打印以ro开头的行;
[[email protected]~]# sed -n "/^ro/p" /etc/passwd
root:x:0:0:root:/root:/bin/bash
3、打印第三到第五行;
[[email protected]~]# cat -n /etc/passwd |sed -n "3,5p"
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
4、打印以r开头的行到s开头的行;
[[email protected]~]# sed -n ‘/^r/,/^d/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
[[email protected]~]# sed -n ‘3,/^s/p‘ /etc/passwd
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
5、打印奇数行和偶数行;
[[email protected]~]# cat -n /etc/passwd |sed -n "1~2p"
1 root:x:0:0:root:/root:/bin/bash
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[[email protected]~]# cat -n /etc/passwd |sed -n "0~2p"
2 bin:x:1:1:bin:/bin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
6、删除第一行
[[email protected]~]# cat -n /etc/passwd |sed "1d"
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
7、练习插入
[[email protected]~]# sed ‘1a/ls‘ /etc/passwd #在第一行后面插入ls
root:x:0:0:root:/root:/bin/bash
/ls
bin:x:1:1:bin:/bin:/sbin/nologin
[[email protected]~]# sed ‘/^bin/a/ls‘ /etc/passwd #在以bin开头的行另起一行插入ls
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
/ls
8、把第一行替换为ls
[[email protected]~]# sed ‘1c/ls‘ /etc/passwd
/ls
bin:x:1:1:bin:/bin:/sbin/nologin
9、显示行号
[[email protected]~]# sed -n ‘/^root/=‘ /etc/passwd
1
10、显示不以root开头的行
[[email protected]~]# sed -n ‘/root/!p‘ /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
练习
1、删除centos7系统/etc/grub2.cfg文件中所有以空白开头的行行首的空白字符
[[email protected]~]#
[[email protected]~]# sed -nr "s/^[[:space:]]//p" f1
root(hd0,0)
kernel/vmlinuz-2.6.32-431.el6.x86_64 roroot=UUID=4d39e709-cd4b-4697-9146-01e41ca2037d rd_NO_LUKS rd_NO_LVMLANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgbquiet
initrd/initramfs-2.6.32-431.el6.x86_64.img
2、删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符
[[email protected]~]# sed -nr "s/^#[[:space:]]*//p" /etc/fstab
/etc/fstab
Createdby anaconda on Wed Jan 20 18:09:49 2016
3、在centos6系统/root/install.log每一行行首增加#号
[[email protected]~]# cat install.log |sed -n "s/.*/#&/p"
#default=0
#timeout=5
#splashimage=(hd0,0)/grub/splash.xpm.gz
#hiddenmenu
4、在/etc/fstab文件中不以#开头的行的行首增加#号
[[email protected]~]# sed "s/^[^#]/#&/p" /etc/fstab
#proc /proc proc defaults 0 0
#/dev/sr0 /media iso9660 defaults 0 0
5、处理/etc/fstab路径,使用sed命令取出其目录名和基名
[[email protected]~]# ls /etc/fstab |sed -nr "[email protected](^/.*/)(.*)@\[email protected]"
fstab
[[email protected]~]# ls /etc/fstab |sed -nr "[email protected](^/.*/)(.*)@\[email protected]"
/etc/
6、利用sed 取出ifconfig命令中本机的IPv4地址
[[email protected]~]# ifconfig |sed -nr "2p"|sed -nr "s/.*addr://p"|sed -nr "s/[[:space:]].*//p"
192.168.1.61
7、统计centos安装光盘中Package目录下的所有rpm文件的以.分隔倒数第二个字段的重复次数
[[email protected]~]# ls /media/Packages/|sed "rpm$" |sed -nr"s/.*\.(.*)\.rpm$/\1/p"|sort |uniq -c
808 i686
937 noarch
2250 x86_64
8、统计/etc/init.d/functions文件中每个单词的出现次数,并排序(用grep和sed两种方法分别实现)
9、将文本文件的n和n+1行合并为一行,n为奇数行
10、样例数据是UNIX shell范例精解(第四版)(UNIXShells by Example Fourth Edition)提供的练习文件cce,内容如下:
SteveBlenheim:238-923-7366:95 Latham Lane, Easton, PA 83755:11/12/56:20300
BettyBoop:245-836-8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500
IgorChevsky:385-375-8395:3567 Populus Place, Caldwell, NJ 23875:6/18/68:23400
NormaCorder:397-857-2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700
JenniferCowan:548-834-2348:583 Laurel Ave., Kingsville, TX 83745:10/1/35:58900
JonDeLoach:408-253-3122:123 Park St., San Jose, CA 04086:7/25/53:85100
KarenEvich:284-758-2857:23 Edgecliff Place, Lincoln , NB 92743:7/25/53:85100
KarenEvich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
KarenEvich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
FredFardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900
FredFardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900
LoriGortz:327-832-5728:3465 Mirlo Street, Peabody, MA 34756:10/2/65:35200
PacoGutierrez:835-365-1284:454 Easy Street, Decatur, IL 75732:2/28/53:123500
EphramHardy:293-259-5395:235 CarltonLane, Joliet, IL 73858:8/12/20:56700
JamesIkeda:834-938-8376:23445 Aster Ave., Allentown, NJ 83745:12/1/38:45000
BarbaraKertz:385-573-8326:832 Ponce Drive, Gzary, IN 83756:12/1/46:268500
LesleyKirstin:408-456-1234:4 Harvard Square, Boston, MA 02133:4/22/62:52600
WilliamKopf:846-836-2837:6937 Ware Road, Milton, PA 93756:9/21/46:43500
SirLancelot:837-835-8257:474 Camelot Boulevard, Bath, WY 28356:5/13/69:24500
JesseNeal:408-233-8971:45 Rose Terrace, San Francisco, CA 92303:2/3/36:25000
ZippyPinhead:834-823-8319:2356 Bizarro Ave., Farmount, IL 84357:1/1/67:89500
ArthurPutie:923-835-8745:23 Wimp Lane, Kensington, DL 38758:8/31/69:126000
PopeyeSailor:156-454-3322:945 Bluto Street, Anywhere, USA 29358:3/19/35:22350
JoseSantiago:385-898-8357:38 Fife Way, Abilene, TX 39673:1/5/58:95600
TommySavage:408-724-0140:1222 Oxbow Court, Sunnyvale, CA 94087:5/19/66:34200
YukioTakeshida:387-827-1095:13 Uno Lane, Ashville, NC 23556:7/1/29:57000
VinhTranh:438-910-7449:8235 Maple Street, Wilmington, VM 29085:9/23/63:68900
练习的内容为:
1. 把Jon的名字改为Jonathan。
[[email protected]~]# sed -i "s/Jon/Jonathan/g" cce
2. 删除头3行。
[[email protected]~]# sed -i "1,3d" cce
3. 打印第5~10行。
[[email protected]~]# cat -n cce |sed -n "5,10p"
5 KarenEvich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
6 KarenEvich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
7 FredFardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900
8 FredFardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900
9 LoriGortz:327-832-5728:3465 Mirlo Street, Peabody, MA 34756:10/2/65:35200
10 PacoGutierrez:835-365-1284:454 Easy Street, Decatur, IL 75732:2/28/53:123500
4. 删除含有Lane的所有行。
[[email protected]~]# sed -i "/Lane/d" cce
5. 打印所有生日在十一月或十二月的行。
[[email protected]~]# sed -n "/:1[12]\//p" cce
通过观察文本发现,在冒号(:)和斜线(/)中间夹着的数字表示生日的月份。
6. 在以Kare开关的行末尾加上3颗星。
[[email protected]~]# sed -i "s/^Kare.*/&***/" cce
7. 将所有包含Jose的行都替换为JOSEHAS RETIRED。
[[email protected]~]# sed -i "s/Jose/JOSE HAS RETIRED/" cce
8. 把Popeye的生日改为11/14/46,假定您不知道Popeye的生日,设法用正则式查找出来。{sed嵌套}
[[email protected]~]# sed -n "/Popeye/{p;[email protected]:[0-9]/[0-9][0-9]/[0-9][0-9]:@:11/14/46:@}"cce
9. 删除所有空行。
[[email protected]~]# sed "/^$/d" cce
11、去掉空行和以#号开头的行
sed -e"/^#/d" -e "/^$/d" cce
SED练习
1.删除文件每行的第一个字符
[[email protected] ~]# sed -n "s/^.//p" cce
oot:x:0:0:root:/root:/bin/bash
2.删除文件每行的第二个字符
[[email protected] ~]# sed -i -r "s/^(.)./\1/" cce
3.删除文件每行的最后一个字符
[[email protected] ~]# sed -n -r "s/(.*)(.)$/\1/p" cce
4.删除文件每行的倒数第二个字符
[[email protected] ~]# sed -nr "s/.(.$)/\1/p" cce
5.删除文件每行的第二个单词
[[email protected] ~]# sed -nr "s/(^[[:alpha:]]+).([[:alpha:]]+)/\1/p" cce
root:0:0:root:/root:/bin/bash
6.删除文件每行的倒数第二个单词
[[email protected] ~]# sed -nr "s/([[:alpha:]]+).([[:alpha:]]+)$/\2/p" cce
root:x:0:0:root:/root:/bash
7.删除文件每行的最后一个单词
[[email protected] ~]# sed -nr "s/([[:alpha:]]+).([[:alpha:]]+)$/\1/p" cce
root:x:0:0:root:/root:/bin
8.交换每行的第一个字符和第二个字符
[[email protected] ~]# sed -nr "s/^([[:alpha:]])([[:alpha:]])/\2\1/p" cce
orot:x:0:0:root:/root:/bin/bash