shell编程四剑客之 sed

前言

在Linux中,一般存在两种文本编辑器,即交互式编辑器和流编辑器,交互式编辑器就是交互式的添加、删除、更改文件内容,我们常用的vi、vim、gedit就是交互式编辑器,而流编辑器则是按照预先定义好的操作规则对文本文件进行添加、删除、更改等操作,今天我们就来讲流编辑器sed。

sed工作模式

sed流编辑器是以为单位进行文本处理的,其基本语法格式如下:

sed [选项] '命令' 文件
sed [选项] -f 脚本文件 文件

说明:以上展示了sed的两种使用方式,目标文件可以是一个文件或多个文件,第一种使用sed内置的命令进行目标文本文件的操作,使用命令可以实现文本的各种操作,但命令要使用单引号括起来;第二种是使用定义好的脚本对目标文件进行操作;

注意:sed是以行为单位的,也就是说,sed会读入目标文件的一行,然后与命令进行匹配,匹配成功则进行对应的操作,然后处理完后继续读入下一行,直到处理完数据流中的全部数据行才停止工作

sed语法

sed [选项] [sed内置的命令] [文件]

最常用的[选项]有下面这些:

-n :默认情况下即使不匹配,sed也会输出不匹配的行,而使用-n可以禁止打印模式空间的不匹配的数据,一般与p连用,表示匹配命令后才明确打印模式空间的数据,如:sed -n '3p' testsed.tex ,如:sed -n  '1s:g:GG:gp' testsed.tex,表示对第一行进行全局搜索并进行字符替换后定义改行,如果不加p,则所有的行都被输出,即使只指定第一行是处理行,即使其他行没有被处理过。
-e :连接多个编辑命令,如:sed -e 's/g/G/g' -e 's/b/B/g' testsed.tex
-i :直接将修改结果写回到源文件,如果不用-i,那么sed修改的只是它模式空间内存的数据
-r :支持正则扩展
-f:指定包含编辑命令的文件,因为sed的编辑命令可以放在一个单独的文件中,当要使用时直接用-f包含过来即可,如:sed -f file.sed testsed.tex

sed的内置命令用于对文件的不同操作,如对文件的增删改查:

i	insert,表示插入文本,在匹配行的前面插入文本
a	append,对文件的追加,值指定行后面追加一行或多行的文本
c   用此符号后的新文本替换当前行中的文本
d	delete,删除匹配的行
p	print,打印匹配的行,一般与选项-n一起使用
s/正则/替换的内容/g	匹配正则表达式,然后替换内容,结尾的g表示全局匹配,s替换命令默认只会替换一行中的第一个匹配的字符串,除非指定全局替换字符g
r	从文件中读取输入行 
w   将所选的行写入文件

可以指定第几行,使用地址定位来实现,如下:

x 				表示指定第x行
x,y 			表示x到y行
/key/ 			表示查询包含关键字key的行
/key1/,/key2/  	表示匹配包含两个关键字之间的行
/key/,x  		从匹配关键字开始到文件第x行
x, /key/ 		从第x行开始到与关键字的匹配行之间的行	
x,y! 			不包含x到y行

演示示例:

# sed的打印输出 

#输入test.txt 文件的2到5行,-n表示不匹配的不要输出,匹配的才输出,p表示打印
sed -n '2p' text.txt			#打印第2行
sed -n '2p,5p' text.txt			#打印第2行和第5行
sed -n '2,5p' text.txt			#打印第2到第5行
sed -n '1!p'  text.txt			#打印除第1行之外的其他行
sed -n '/nologin$/p' text.txt	#打印以nologin结尾的行
# sed查找字符并打印输出字符的行

sed -n '/disabled/p' /etc/selinux/config  #在两个分割符之间写要匹配的disabled字符
sed -n '/root/p' test.txt 					#查找root的行并打印输出
# sed删除包含字符的行
#-i表示将修改结果写回到源文件,如果不用-i,那么sed修改的只是它模式空间内存的数据,文件并没有改变,所以需要使用-i参数
# d	表示delete,删除匹配的行

sed -i '/systemd/d' text.txt		  		#删除有systemd的行
sed -i '1,6503d' text.ttx		  			#删除第1行到第6503行
sed -i '1d;6d' text.ttx			 			#删除第1行和第6行 
sed -i '5,$d' test.txt 						#删除第5行到末尾行
```bash
# sed插入字符
# i表示insert插入,是在行前面插入,a表示append追加,是在行末尾追加
sed -i '1iI am guo' text.txt				#在第1行前面插入I am guo
sed -i '4aI am guo' text.txt				#在第4行后面插入I am guo
sed -i '1iI am guo.\nGood man' text.txt		#在第1行前面插入I am guo,然后换行后插入了Good man
sed -i '4iI am fullsh;6aI am good man' text.txt	#错误的,在第4行前面插入I am fullsh,在第6行后面插入I am good man (不行)
sed -i -e '4iI am fullsh' -e '6aI am good man' text.txt		#正确的,在第4行前面插入I am fullsh,在第6行后面插入I am good man (正确的)

sed -i '4,6iI am good man' text.txt			#在第4行到第6行的行的前面插入I am good man
sed -i 'ihello world' text.txt				#每一行(没有指定数字就是每一行)的前面插入hello world
sed -i 'aI am guo,I am good man.' text.txt	#在每一行(没有指定数字就是每一行)后面添加一行I am guo,I am good man.

sed -i '$ihello world'  text.txt			#在最后一行的前面插入字符串hello world
sed -i '$ahello world'  text.txt			#在最后一行的后面插入字符串hello world

sed '2cI am good man' text.txt				#c表示使用字符替换整行,使用I am good man替换第2行

sed '2r /home/file.txt' text.txt			#r表示从文件读取行,从/home/file.txt文件读取行插入text.txt的第2行后面
sed '$r /home/file.txt' text.txt			#从/home/file.txt文件读取行插入text.txt的最后面

sed '1,5w /home/file.txt' text.txt			#w表示写入文件,表示将text.txt中的第1行到第5行覆盖到/home/file.txt中
# sed 的替换
# -i表示将修改结果写回到源文件,如果不用-i,那么sed修改的只是它模式空间内存的数据,文件并没有改变,所以需要使用-i参数
# s/正则/替换的内容/g	  匹配正则表达式,然后替换内容,结尾的g表示全局匹配,s替换命令默认只会替换一行中的第一个匹配的字符串,除非指定全局替换字符g
sed -i  's/daemon/GOOD/g' test.txt						# 将全部的daemon替换为GOOD
sed -i  's#daemon#GOOD#g' test.txt						# 分隔符其实可以使用#号,此条等价于上面一条
sed -ri 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config  #常用,-r表示支持正则表达式
sed -i 's/nologin/login/g;s/ceph/CEPH/g' text.txt 		#将全局的nologin替换为login,ceph替换为CEPH

# sed 使用 -e 连接多条命令
# 将全部的daemon替换为DAEMON,同时也将全部的nologin替换为NOLOGIN
# -e :连接多个编辑命令,-i表示写回源文件,g表示全局替换
# 要使用2个-e参数
sed -i -e 's/daemon/DAEMON/g' -e 's/nologin/NOLOGIN/g' test.txt 
正则:
sed -i 's/^root/#&/' text.txt			#注释掉以root开头的行
sed -rn '/^rpc|^mail/p' text.txt		#打印rpc开头或mail开头的行
sed -rn '/false$/p' text.txt			#打印false结尾的行

猜你喜欢

转载自blog.csdn.net/MssGuo/article/details/117596128