typora-root-url: …\\pictures
#课程目标
- 掌握sed的基本语法结构
- 熟悉sed常用的命令,如打印p,删除d,插入i等
一、文件编辑器知多少
- Windows系统
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YWFupr2x-1591061915348)(./edit.png)]
- Linux系统
vim vi gedit nano emacs
#二、强悍的sed介绍
1. sed用来做啥?
sed是Stream Editor(流编辑器)的缩写,简称流编辑器;用来处理文件的。
2. sed如何处理文件?
sed是一行一行读取文件内容并按照要求进行处理,把处理后的结果输出到屏幕。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kbWmVxwQ-1591061915351)(./sed.png)]
- 首先sed读取文件中的一行内容,把其保存在一个临时缓存区中(也称为模式空间)
- 然后根据需求处理临时缓冲区中的行,完成后把该行发送到屏幕上
总结:
- 由于sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会直接修改原文件
- Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作,对文件进行过滤和转换操作
#三、sed使用方法介绍
sed常见的语法格式有两种,一种叫命令行模式,另一种叫脚本模式。
1. 命令行格式
㈠ 语法格式
sed [options] ’处理动作**’** 文件名
- 常用选项
选项 | 说明 | 备注 |
---|---|---|
-e | 进行多项(多次)编辑 | |
-n | 取消默认输出 | 不自动打印模式空间 |
-r | 使用扩展正则表达式 | |
-i | 原地编辑(修改源文件) | |
-f | 指定sed脚本的文件名 |
- 常见处理动作
丑话说在前面:以下所有的动作都要在单引号里,你敢出轨,回家跪搓衣板
动作 | 说明 | 备注 |
---|---|---|
‘p’ | 打印 | |
‘i’ | 在指定行之前插入内容 | 类似vim里的大写O |
‘a’ | 在指定行之后插入内容 | 类似vim里的小写o |
‘c’ | 替换指定行所有内容 | |
‘d’ | 删除指定行 |
㈡ 举例说明
- 文件准备
# vim a.txtroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin298374837483172.16.0.25410.1.1.1
① 对文件进行增、删、改、查操作
语法:sed 选项 \’定位+命令’ 需要处理的文件
1)打印文件内容
[root@server ~]# sed \'\' a.txt 对文件什么都不做[root@server ~]# sed -n \'p\' a.txt 打印每一行,并取消默认输出[root@server ~]# sed -n \'1p\' a.txt 打印第1行[root@server ~]# sed -n \'2p\' a.txt 打印第2行[root@server ~]# sed -n \'1,5p\' a.txt 打印1到5行[root@server ~]# sed -n \'$p\' a.txt 打印最后1行
2)增加文件内容
i 地址定位的上面插入
a 下面插入
[root@server ~]# sed \'$a99999\' a.txt 文件最后一行下面增加内容[root@server ~]# sed \'a99999\' a.txt 文件每行下面增加内容[root@server ~]# sed \'5a99999\' a.txt 文件第5行下面增加内容[root@server ~]# sed \'$i99999\' a.txt 文件最后一行上一行增加内容[root@server ~]# sed \'i99999\' a.txt 文件每行上一行增加内容[root@server ~]# sed \'6i99999\' a.txt 文件第6行上一行增加内容[root@server ~]# sed \'/^uucp/ihello\' 以uucp开头行的上一行插入内容
3)修改文件内容
c 替换指定的整行内容
[root@server ~]# sed \'5chello world\' a.txt 替换文件第5行内容[root@server ~]# sed \'chello world\' a.txt 替换文件所有内容[root@server ~]# sed \'1,5chello world\' a.txt 替换文件1到5号内容为hello world[root@server ~]# sed \'/^user01/c888888\' a.txt 替换以user01开头的行
4)删除文件内容
[root@server ~]# sed \'1d\' a.txt 删除文件第1行[root@server ~]# sed \'1,5d\' a.txt 删除文件1到5行[root@server ~]# sed \'$d\' a.txt 删除文件最后一行
② 对文件进行搜索替换操作
语法:sed 选项 ‘s/搜索的内容/替换的内容/动作’ 需要处理的文件
其中,s表示search搜索;斜杠/表示分隔符,可以自己定义;动作一般是打印p和全局替换g
[root@server ~]# sed -n \'s/root/ROOT/p\' 1.txt[root@server ~]# sed -n \'s/root/ROOT/gp\' 1.txt[root@server ~]# sed -n \'s/^#//gp\' 1.txt[root@server ~]# sed -n \'s@/sbin/nologin@itcast@gp\' a.txt[root@server ~]# sed -n \'s/\\/sbin\\/nologin/itcast/gp\' a.txt[root@server ~]# sed -n \'10s#/sbin/nologin#itcast#p\' a.txtuucp:x:10:14:uucp:/var/spool/uucp:itcast[root@server ~]# sed -n \'s@/sbin/nologin@itcastheima@p\' 2.txt注意:搜索替换中的分隔符可以自己指定[root@server ~]# sed -n \'1,5s/^/#/p\' a.txt 注释掉文件的1-5行内容#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 | 从另外文件中读取内容 | |
w | 内容另存为 | |
& | 保存查找串以便在替换串中引用 | 和\\(\\)相同 |
= | 打印行号 | |
! | 对所选行以外的所有行应用命令,放到行数之后 | ‘1,5!’ |
q | 退出 |
举例说明:
r 从文件中读取输入行w 将所选的行写入文件[root@server ~]# sed \'3r /etc/hosts\' 2.txt[root@server ~]# sed \'$r /etc/hosts\' 2.txt[root@server ~]# sed \'/root/w a.txt\' 2.txt[root@server ~]# sed \'/[0-9]{4}/w a.txt\' 2.txt[root@server ~]# sed -r \'/([0-9]{1,3}\\.){3}[0-9]{1,3}/w b.txt\' 2.txt! 对所选行以外的所有行应用命令,放到行数之后[root@server ~]# sed -n \'1!p\' 1.txt[root@server ~]# sed -n \'4p\' 1.txt[root@server ~]# sed -n \'4!p\' 1.txt[root@server ~]# cat -n 1.txt[root@server ~]# sed -n \'1,17p\' 1.txt[root@server ~]# sed -n \'1,17!p\' 1.txt& 保存查找串以便在替换串中引用 \\(\\)[root@server ~]# sed -n \'/root/p\' a.txtroot:x:0:0:root:/root:/bin/bash[root@server ~]# sed -n \'s/root/#&/p\' a.txt#root:x:0:0:root:/root:/bin/bash# sed -n \'s/^root/#&/p\' passwd 注释掉以root开头的行# sed -n -r \'s/^root|^stu/#&/p\' /etc/passwd 注释掉以root开头或者以stu开头的行# sed -n \'1,5s/^[a-z].*/#&/p\' passwd 注释掉1~5行中以任意小写字母开头的行# sed -n \'1,5s/^/#/p\' /etc/passwd 注释1~5行或者sed -n \'1,5s/^/#/p\' passwd 以空开头的加上#sed -n \'1,5s/^#//p\' passwd 以#开头的替换成空[root@server ~]# sed -n \'/^root/p\' 1.txt[root@server ~]# sed -n \'s/^root/#&/p\' 1.txt[root@server ~]# sed -n \'s/\\(^root\\)/#\\1/p\' 1.txt[root@server ~]# sed -nr \'/^root|^stu/p\' 1.txt[root@server ~]# sed -nr \'s/^root|^stu/#&/p\' 1.txt= 打印行号# sed -n \'/bash$/=\' passwd 打印以bash结尾的行的行号# sed -ne \'/root/=\' -ne \'/root/p\' passwd# sed -n \'/nologin$/=;/nologin$/p\' 1.txt# sed -ne \'/nologin$/=\' -ne \'/nologin$/p\' 1.txtq 退出# sed \'5q\' 1.txt# sed \'/mail/q\' 1.txt# sed -r \'/^yunwei|^mail/q\' 1.txt[root@server ~]# sed -n \'/bash$/p;10q\' 1.txtROOT:x:0:0:root:/root:/bin/bash综合运用:[root@server ~]# sed -n \'1,5s/^/#&/p\' 1.txt#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[root@server ~]# sed -n \'1,5s/\\(^\\)/#\\1/p\' 1.txt#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
④ 其他选项
-e 多项编辑-r 扩展正则-i 修改原文件[root@server ~]# sed -ne \'/root/p\' 1.txt -ne \'/root/=\'root:x:0:0:root:/root:/bin/bash1[root@server ~]# sed -ne \'/root/=\' -ne \'/root/p\' 1.txt1root:x:0:0:root:/root:/bin/bash在1.txt文件中的第5行的前面插入“hello world”;在1.txt文件的第8行下面插入“哈哈哈哈”[root@server ~]# sed -e \'5ihello world\' -e \'8a哈哈哈哈哈\' 1.txt -e \'5=;8=\'sed -n \'1,5p\' 1.txtsed -ne \'1p\' -ne \'5p\' 1.txtsed -ne \'1p;5p\' 1.txt过滤vsftpd.conf文件中以#开头和空行:[root@server ~]# grep -Ev \'^#|^$\' /etc/vsftpd/vsftpd.conf[root@server ~]# sed -e \'/^#/d\' -e \'/^$/d\' /etc/vsftpd/vsftpd.conf[root@server ~]# sed \'/^#/d;/^$/d\' /etc/vsftpd/vsftpd.conf[root@server ~]# sed -r \'/^#|^$/d\' /etc/vsftpd/vsftpd.conf过滤smb.conf文件中生效的行:# sed -e \'/^#/d\' -e \'/^;/d\' -e \'/^$/d\' -e \'/^\\t$/d\' -e \'/^\\t#/d\' smb.conf# sed -r \'/^(#|$|;|\\t#|\\t$)/d\' smb.conf# sed -e \'/^#/d\' -e \'/^;/d\' -e \'/^$/d\' -e \'/^\\t$/d\' -e \'/^\\t#/\' smb.conf[root@server ~]# grep \'^[^a-z]\' 1.txt[root@server ~]# sed -n \'/^[^a-z]/p\' 1.txt过滤出文件中的IP地址:[root@server ~]# grep -E \'([0-9]{1,3}\\.){3}[0-9]{1,3}\' 1.txt192.168.0.254[root@server ~]# sed -nr \'/([0-9]{1,3}\\.){3}[0-9]{1,3}/p\' 1.txt192.168.0.254[root@server ~]# grep -o -E \'([0-9]{1,3}\\.){3}[0-9]{1,3}\' 2.txt10.1.1.110.1.1.255255.255.255.0[root@server ~]# sed -nr \'/([0-9]{1,3}\\.){3}[0-9]{1,3}/p\' 2.txt10.1.1.110.1.1.255255.255.255.0过滤出ifcfg-eth0文件中的IP、子网掩码、广播地址[root@server shell06]# grep -Eo \'([0-9]{1,3}\\.){3}[0-9]{1,3}\' ifcfg-eth010.1.1.1255.255.255.010.1.1.254[root@server shell06]# sed -nr \'/([0-9]{1,3}\\.){3}[0-9]{1,3}/p\' ifcfg-eth0|cut -d\'=\' -f210.1.1.1255.255.255.010.1.1.254[root@server shell06]# sed -nr \'/([0-9]{1,3}\\.){3}[0-9]{1,3}/p\' ifcfg-eth0|sed -n \'s/[A-Z=]//gp\'10.1.1.1255.255.255.010.1.1.254[root@server shell06]# ifconfig eth0|sed -n \'2p\'|sed -n \'s/[:a-Z]//gp\'|sed -n \'s/ /\\n/gp\'|sed \'/^$/d\'10.1.1.110.1.1.255255.255.255.0[root@server shell06]# ifconfig | sed -nr \'/([0-9]{1,3}\\.)[0-9]{1,3}/p\' | head -1|sed -r \'s/([a-z:]|[A-Z/t])//g\'|sed \'s/ /\\n/g\'|sed \'/^$/d\'[root@server shell06]# ifconfig eth0|sed -n \'2p\'|sed -n \'s/.*addr:\\(.*\\) Bcast:\\(.*\\) Mask:\\(.*\\)/\\1\\n\\2\\n\\3/p\'10.1.1.110.1.1.255255.255.255.0-i 选项 直接修改原文件# sed -i \'s/root/ROOT/;s/stu/STU/\' 11.txt# sed -i \'17{s/YUNWEI/yunwei/;s#/bin/bash#/sbin/nologin#}\' 1.txt# sed -i \'1,5s/^/#&/\' a.txt注意:-ni 不要一起使用p命令 不要再使用-i时使用
⑤ sed结合正则使用
sed 选项 \’sed命令或者正则表达式或者地址定位==’== 文件名
- 定址用于决定对哪些行进行编辑。地址的形式可以是数字、正则表达式、或二者的结合。
- 如果没有指定地址,sed将处理输入文件的所有行。
正则 | 说明 | 备注 |
---|---|---|
/key/ | 查询包含关键字的行 | sed -n ‘/root/p’ 1.txt |
/key1/,/key2/ | 匹配包含两个关键字之间的行 | sed -n ‘/^adm/,/^mysql/p’ 1.txt |
/key/,x | 从匹配关键字的行开始到文件第x行之间的行(包含关键字所在行) | sed -n ‘/^ftp/,7p’ |
x,/key/ | 从文件的第x行开始到与关键字的匹配行之间的行 | |
x,y! | 不包含x到y行 | |
/key/! | 不包括关键字的行 | sed -n ‘/bash$/!p’ 1.txt |
##2. 脚本格式
㈠ 用法
# sed -f scripts.sh file //使用脚本处理文件建议使用 ./sed.sh file脚本的第一行写上#!/bin/sed -f1,5ds/root/hello/g3i7775i888a999p
㈡ 注意事项
1) 脚本文件是一个sed的命令行清单。\'commands\'2) 在每行的末尾不能有任何空格、制表符(tab)或其它文本。3) 如果在一行中有多个命令,应该用分号分隔。4) 不需要且不可用引号保护命令5) #号开头的行为注释
㈢举例说明
# cat passwdstu3:x:509:512::/home/user3:/bin/bashstu4:x:510:513::/home/user4:/bin/bashstu5:x:511:514::/home/user5:/bin/bash# cat sed.sh#!/bin/sed -f2a\\******************2,$s/stu/user/$a\\we inster new lines/^[a-z].*/#&/[root@server ~]# cat 1.sed#!/bin/sed -f3a**********************$chelloworld1,3s/^/#&/[root@server ~]# sed -f 1.sed -i 11.txt[root@server ~]# cat 11.txt#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/nologinhelloworld
##3. 补充扩展总结
1、正则表达式必须以”/“前后规范间隔例如:sed \'/root/d\' file例如:sed \'/^root/d\' file2、如果匹配的是扩展正则表达式,需要使用-r选来扩展sedgrep -Esed -r+ ? () {n,m} | \\d注意:在正则表达式中如果出现特殊字符(^$.*/[]),需要以前导 \"\\\" 号做转义eg:sed \'/\\$foo/p\' file3、逗号分隔符例如:sed \'5,7d\' file 删除5到7行例如:sed \'/root/,/ftp/d\' file删除第一个匹配字符串\"root\"到第一个匹配字符串\"ftp\"的所有行本行不找 循环执行4、组合方式例如:sed \'1,/foo/d\' file 删除第一行到第一个匹配字符串\"foo\"的所有行例如:sed \'/foo/,+4d\' file 删除从匹配字符串”foo“开始到其后四行为止的行例如:sed \'/foo/,~3d\' file 删除从匹配字符串”foo“开始删除到3的倍数行(文件中)例如:sed \'1~5d\' file 从第一行开始删每五行删除一行例如:sed -nr \'/foo|bar/p\' file 显示配置字符串\"foo\"或\"bar\"的行例如:sed -n \'/foo/,/bar/p\' file 显示匹配从foo到bar的行例如:sed \'1~2d\' file 删除奇数行例如:sed \'0-2d\' file 删除偶数行 sed \'1~2!d\' file5、特殊情况例如:sed \'$d\' file 删除最后一行例如:sed \'1d\' file 删除第一行6、其他:sed \'s/.//\' a.txt 删除每一行中的第一个字符sed \'s/.//2\' a.txt 删除每一行中的第二个字符sed \'s/.//N\' a.txt 从文件中第N行开始,删除每行中第N个字符(N>2)sed \'s/.$//\' a.txt 删除每一行中的最后一个字符[root@server ~]# cat 2.txt1 a2 b3 c4 d5 e6 f7 u8 k9 o[root@server ~]# sed \'/c/,~2d\' 2.txt1 a2 b5 e6 f7 u8 k9 o
#四、课堂练习
- 将任意数字替换成空或者制表符
- 去掉文件1-5行中的数字、冒号、斜杠
- 匹配root关键字替换成hello itcast,并保存到test.txt文件中
- 删除vsftpd.conf、smb.conf、main.cf配置文件里所有注释的行及空行(不要直接修改原文件)
- 使用sed命令截取自己的ip地址
- 使用sed命令一次性截取ip地址、广播地址、子网掩码
- 注释掉文件的2-3行和匹配到以root开头或者以ftp开头的行
1、将文件中任意数字替换成空或者制表符2、去掉文件1-5行中的数字、冒号、斜杠3、匹配root关键字的行替换成hello itcast,并保存到test.txt文件中4、删除vsftpd.conf、smb.conf、main.cf配置文件里所有注释的行及空行(不要直接修改原文件)5、使用sed命令截取自己的ip地址# ifconfig eth0|sed -n \'2p\'|sed -n \'s/.*addr://pg\'|sed -n \'s/Bcast.*//gp\'10.1.1.1# ifconfig eth0|sed -n \'2p\'|sed \'s/.*addr://g\'|sed \'s/ Bcast:.*//g\'6、使用sed命令一次性截取ip地址、广播地址、子网掩码# ifconfig eth0|sed -n \'2p\'|sed -n \'s#.*addr:\\(.*\\) Bcast:\\(.*\\) Mask:\\(.*\\)#\\1\\n\\2\\n\\3#p\'10.1.1.110.1.1.255255.255.255.07、注释掉文件的2-3行和匹配到以root开头或者以ftp开头的行# sed -nr \'2,3s/^/#&/p;s/^ROOT|^ftp/#&/p\' 1.txt#ROOT:x:0:0:root:/root:/bin/bash#bin:x:1:1:bin:/bin:/sbin/nologin#3daemon:x:2:2:daemon:/sbin:/sbin/nologin# sed -ne \'1,2s/^/#&/gp\' a.txt -nre \'s/^lp|^mail/#&/gp\'# sed -nr \'1,2s/^/#&/gp;s/^lp|^mail/#&/gp\' a.txt
#五、课后实战
1、写一个初始化系统的脚本
1)自动修改主机名(如:ip是192.168.0.88,则主机名改为server88.itcast.cc)
a. 更改文件非交互式 sed
/etc/sysconfig/network
b.将本主机的IP截取出来赋值给一个变量ip;再然后将ip变量里以.分割的最后一位赋值给另一个变量ip1
2)自动配置可用的yum源
3)自动关闭防火墙和selinux
2、写一个搭建ftp服务的脚本,要求如下:
1)不支持本地用户登录 local_enable=NO
2) 匿名用户可以上传 新建 删除 anon_upload_enable=YES anon_mkdir_write_enable=YES
3) 匿名用户限速500KBps anon_max_rate=500000
仅供参考:#!/bin/bashipaddr=`ifconfig eth0|sed -n \'2p\'|sed -e \'s/.*inet addr:\\(.*\\) Bcast.*/\\1/g\'`iptail=`echo $ipaddr|cut -d\'.\' -f4`ipremote=192.168.1.10#修改主机名hostname server$iptail.itcast.comsed -i \"/HOSTNAME/cHOSTNAME=server$iptail.itcast.com\" /etc/sysconfig/networkecho \"$ipaddr server$iptail.itcast.cc\" >>/etc/hosts#关闭防火墙和selinuxservice iptables stopsetenforce 0 >/dev/null 2>&1sed -i \'/^SELINUX=/cSELINUX=disabled\' /etc/selinux/config#配置yum源(一般是内网源)#test networkping -c 1 $ipremote > /dev/null 2>&1if [ $? -ne 0 ];thenecho \"你的网络不通,请先检查你的网络\"exit 1elseecho \"网络ok.\"ficat > /etc/yum.repos.d/server.repo << end[server]name=serverbaseurl=ftp://$ipremoteenabled=1gpgcheck=0end#安装软件read -p \"请输入需要安装的软件,多个用空格隔开:\" softyum -y install $soft &>/dev/null#备份配置文件conf=/etc/vsftpd/vsftpd.conf\\cp $conf $conf.default#根据需求修改配置文件sed -ir \'/^#|^$/d\' $confsed -i \'/local_enable/c\\local_enable=NO\' $confsed -i \'$a anon_upload_enable=YES\' $confsed -i \'$a anon_mkdir_write_enable=YES\' $confsed -i \'$a anon_other_write_enable=YES\' $confsed -i \'$a anon_max_rate=512000\' $conf#启动服务service vsftpd restart &>/dev/null && echo\"vsftpd服务启动成功\"#测试验证chmod 777 /var/ftp/pubcp /etc/hosts /var/ftp/pub#测试下载cd /tmplftp $ipaddr <<endcd pubget hostsexitendif [ -f /tmp/hosts ];thenecho \"匿名用户下载成功\"rm -f /tmp/hostselseecho \"匿名用户下载失败\"fi#测试上传、创建目录、删除目录等cd /tmplftp $ipaddr << endcd pubmkdir test1mkdir test2put /etc/grouprmdir test2exitendif [ -d /var/ftp/pub/test1 ];thenecho \"创建目录成功\"if [ ! -d /var/ftp/pub/test2 ];thenecho \"文件删除成功\"fielseif [ -f /var/ftp/pub/group ];thenecho \"文件上传成功\"elseecho \"上传、创建目录删除目录部ok\"fifi[ -f /var/ftp/pub/group ] && echo \"上传文件成功\"