一、sed工具介绍
sed是一种流编辑器,是一个面向行的处理工具,可以实现对文本的增删改查和替换,可以同时处理多个文件多行内容,可以通过不同的方式去处理文本得到自己想要的结果,是一个功能非常强大的文本编辑处理工具。
二、sed的基本使用
用法1:前置命令 | sed [选项] ‘条件指令’
用法2:sed [选项] ‘条件指令’ 文件
相关说明如下:
条件可以是行号或者/正则/
没有条件时,默认为所有条件
指令可以是增、删、改、查等指令
默认sed会将所有输出内容都打印出来,可以使用-n屏蔽默认输出
选项中可以使用-r选项,让sed支持扩展正则
sed命令的常用选项如下:
选项 | 作用 |
---|---|
-n | 屏蔽默认输出,默认sed会输出读取文档的全部内容 |
-r | 可以使用sed支持扩展正则 |
-i | 使sed直接修改源文件,默认sed只是通过内存临时修改文件,源文件无影响 |
指令 | 作用 |
---|---|
p | 打印 |
d | 删除 |
s | 替换 |
a | 追加,在指定的行之后追加文本 |
i | 插入,在指定的行之前插入文本 |
c | 替换行,替换指定的行 |
sed命令的-n选项
执行p打印等过滤操作时,希望看到的是符合条件的文本。但不使用任何选项时,默认会将原始文本一并输出,从而干扰过滤效果。比如,尝试用sed输出/etc/hosts的第1行:
可以发现所有的行都被显示出来了(第1行重复2次)。—— 正确的用法应该添加 -n 选项,这样就可以只显示第1行了:
行号可以使连续的行号,如打印passwd第3行到第6行账号信息:
sed命令-i选项:
正常情况下,sed命令所做的处理只是把操作结果(包括打印、删除等)输出到当前终端屏幕,而并不会对原始文件做任何更改,如下:
删除/etc/hosts文件的所有内容,不加-i选项:
可以发现源文件的内容并没有被修改,若是想直接修改源文件,则要添加选项-i,可以自己随便创建一个文件试试,如下:
sed使用多个指令要用“;”(分号)隔离,如:
打印文件的第1行和第3行:
三、sed工具的条件使用:
sed [选项] ‘条件指令’ 文件
sed命令可以使用行号或正则作为条件匹配:
##使用d指令跟p指令同理,只要把p换成d就可以了
1.行号案例:
[root@redhat ~]#sed -n '2p' /etc/passwd //打印文件第2行
[root@redhat ~]#sed -n '3,5p' /etc/passwd //打印文件第3到5行
[root@redhat ~]# sed -n '3p;5p' /etc/passwd //打印文件的第3行和第5行`
[root@redhat ~]#sed -n '3,+10p' /etc/passwd //打印文件第3行及第3行后面的10行
[root@redhat ~]#sed -n '1~2p' /etc/passwd //打印文件第1行以及后面每隔两行打印一次,也就是打印奇数行
[root@redhat ~]#sed -n '2~2p' /etc/passwd //打印文件第2行以及后面每隔两行打印一次,也就是打印偶数行
2.正则案例:
[root@redhat ~]#sed -n '/root/p' /etc/passwd //打印文件中包含root的行
[root@redhat ~]#sed -n '/bash$/p' /etc/passwd //打印文件中以bash结尾的行
[root@redhat ~]#sed -n 'p' /etc/passwd //没有条件,表示匹配所有的行,也就是会输出文件中所有的内容
[root@redhat ~]#sed -n '$=' /etc/passwd //输出文件的行数
[root@redhat ~]#sed -n '/^$/d /etc/passwd //删除文件的空行
[root@redhat ~]#sed -n /root/!d' /etc/passwd //删除不包含root的行,!表示取反
3.sed工具的替换功能:
用法:sed ‘s/旧内容/新内容/选项’ 文件
注意:替换操作的分隔符"/"可以改用为其他的字符代替,例如#,$,&等
sed工具的s指令替换案例集锦:
[root@redhat ~]#sed 's/aaa/AAA/' filename //将每行中的第1个aaa替换为AAA
[root@redhat ~]#sed 's/aaa/AAA/3' filename //将每行中的第3个aaa替换为AA
[root@redhat ~]#sed 's/aaa/AAA/g' 文件名 //将文件中所有的aaa替换为AAA
[root@redhat ~]#sed -n '1s/aaa/AAA/p' filename //将文件第1行的第一个aaa替换为AAA
[root@redhat ~]#sed -n '1s/aaa/AAA/gp' filename //将文件第1行的所有aaa全替换为AAA
[root@redhat ~]#sed 's/aaa//g' filename //将文件中所有的aaa替换为空(也就是删除aaa)
[root@redhat ~]#sed 's#/bin/bash#/bin/sh#g' /etc/passwd //将/etc/passed文件中的所有/bin/bash替换为/bin/sh
[root@redhat ~]#sed '3,5s/^/#/' filename //在文件中的第3-5行前面加上#号,也就是把第3-5行注释掉
[root@redhat ~]#sed 's/^#a/a/' filename //将文件中以a开头的行的注释去掉,删除#号
四、sed工具使用案例:
参考数据文件内容如下:
[root@redhat ~]#cat a.txt
wo shi redhat7
ni shi centos6
1.删除文件中每一行的第二个和最后一个字符:
思路:可以分为两步操作,先替换掉第2个字符,再替换掉最后一个字符;
[root@redhat ~]#sed 's/.//2;s/.$//' a.txt
2.将文件中每一行的第一个和倒数第一个字符互换位置:
思路:每行的文本的内容可以拆分为“第1个字符”、“中间的字符”、“倒数第一个字符”三个部分,然后通过替换操作配合正则重新将文档的内容重新排序;
[root@redhat ~]#sed -r 's/^(.)(.*)(.)$/\3\2\1/' a.txt
3.删除文件中的数字:
[root@redhat ~]#sed -r 's/[0-9]//' a.txt
4.删除文件每行倒数第2个字符:
思路:每行的文本的内容可以拆分为“前面的字符”、“倒数第2个字符”、“倒数第一个字符”三个部分,通过替换操作配合正则重新将文档的内容重新排序将倒数第二个字符去掉;
[root@redhat ~]#sed -r 's/^(.*)(.)(.)$/\1\3/' a.txt
5.删除文件的第二个单词:
思路1:可以将每一行的内容分为五个部分,“第一个单词”,“空格”,“第二个单词”,“空格”,“第三个单词”,然后通过替换操作将每一行重新排序去掉第二个单词,下面每一行就是一种处理方法:
[root@redhat ~]#sed -r 's/(.+)([^a-Z0-9])([a-Z0-9]+)([^a-Z0-9])([a-Z0-9]+)/\1\2\4\5/' a.txt
[root@redhat ~]#sed -r 's/([a-Z0-9]+)([^a-Z0-9])([a-Z0-9]+)([^a-Z0-9])([a-Z0-9]+)/\1\2\4\5/' a.txt
[root@redhat ~]#sed -r 's/([a-Z0-9]{1,})([^a-Z0-9])([a-Z0-9]{1,})([^a-Z0-9])([a-Z0-9]{1,})/\1\2\4\5/' a.txt
[root@redhat ~]#sed -r 's/([a-Z0-9]+)([^a-Z0-9])(.*)([^a-Z0-9])([a-Z0-9]+)/\1\2\4\5/' a.txt
[root@redhat ~]#sed -r 's/([a-Z]+)([[:space:]])([a-Z0-9]+)([[:space:]])([a-Z0-9]+)/\1\2\4\5/' a.txt
思路2(适合不够严谨的场合):将文件每行的内容分为3部分,每一个单词为一个部分,不管空格,然后通过替换操作将每一行重新排序去掉第二个单词,同时在第一跟第三个单词之间加上tab键,可以将第一跟第三个单词隔开,下面每一行就是一种处理方法:
[root@redhat ~]#sed -r 's/([a-Z]{1,}) ([a-Z]{1,}) ([a-Z]{1,})/\1\t\3/' a.txt
[root@redhat ~]#sed -r 's/([a-Z]+) ([a-Z]+) ([a-Z]+)/\1\t\3/' a.txt
[root@redhat ~]#sed -r 's/(.+) ([a-Z]+) ([a-Z]+)/\1\t\3/' a.txt
6.将文件中每一行的第一个单词跟最后一个单词调换位置:
思路:思路跟上面差不多,同样是将文件中的内容分为五部分,“第一个单词”,“空格”,“第二个单词”,“空格”,“第三个单词”,然后通过替换操作将每一行重新排序将第一个单词跟组后一个单词调换位置(12345–>52341),下面每一行就是一种处理方法:
[root@redhat ~]# sed -r 's/([a-Z0-9]+)([^a-Z0-9])(.*)([^a-Z0-9])([a-Z0-9]+)/\5\2\3\4\1/' a.txt
[root@redhat ~]# sed -r 's/([a-Z0-9]+)([^a-Z0-9])([a-Z0-9]+)([^a-Z0-9])([a-Z0-9]+)/\5\2\3\4\1/' a.txt
**#不同的方法可以参考上面**
五、利用sed工具修改系统配置(当前使用的是redhat7.4版本的系统),如下:
编写脚本vsftp.sh,修改简单修改服务配置,实现以下任务需求:
任务需求:
通过yum安装vsftpd软件包
修改vsftpd服务配置,开启匿名上传
调整/var/ftp/pub目录权限,允许写入
启动vsftpd服务,并设置开机自运行
思路分析:
a.vsftpd服务的安装、改目录权限、起服务等操作可以直接写在脚本中。
b.修改vsftpd.conf配置的工作可以使用sed命令,根据默认配置,只需要定位到以#anon开头的行,去掉开头的注释即可。
[root@redhat ~]# vim vsftp.sh
#!/bin/bash
yum -y install vsftpd //安装vsftpd软件
cp /etc/vsftpd/vsftpd.conf{,.bak} //备份默认的配置文件,新的文件命名为vsftpd.conf.bak,同样在/etc/vsftpd/目录下
sed -i "s/^#anon/anon/" /etc/vsftpd/vsftpd.conf //修改服务配置
chmod 777 /var/ftp/pub //调整目录权限
systemctl start vsftpd //启动服务
systemctl enable vsftpd //将服务设置为开机自启动
[root@redhat ~]# chmod +x vsftp.sh //给脚本赋予执行权限
[root@redhat ~]# ./vsftp.sh //运行脚本验证
六、sed多行文本处理
用法:sed [选项] ‘条件指令’ 文件
sed工具的多行文本处理操作:
i: 在指定的行之前插入文本
a:在指定的行之后追加文本
c:替换指定的行
[root@redhat ~]#sed '2a XX' a.txt //在第二行后面,追加XX
[root@redhat ~]#sed '2i XX' a.txt //在第二行前面,插入XX
[root@redhat ~]#sed '2c XX' a.txt 将第二行替换为XX