流编辑器sed
sed本身也是一个管线命令,可以分析standard input,而且sed 还可将数据进行取代、删除、新增、撷取特定行等等的功能。
(1)了解sed这个编辑器
刚学linux时我们首先接触的就是vim编辑器,它是Linux中最基础的文本编辑器。其实sed也可以执行与vim编辑器相同的编辑内容。不过,sed编辑器并没有提供交互式使用方式,使用者只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出。(我好像还没写过vim编辑器的文章,改天补上~)
(2)sed编辑器是怎么工作的?
sed 编辑器可以逐行处理文件(或输入),并将结果输送到屏幕。sed 会把当前正在处理的行保存在一个临时缓存区中,这个缓存区称为模式空间或临时缓冲,在处理完模式空间中的行后(即在该行上执行完sed命令后),就把该行发送到屏幕上。
在运行过程中,sed把每一行都存在临时缓存区中,对这个副本进行编辑,所以不会修改或破坏源文件。
sed命令格式
sed [options] ‘Adress Command1;Command2;...’ filename
详细介绍一下它命令格式的内容:
- [options]为参数,常用参数选项有这么几个:
-- -n: 只将被sed特殊处理的行输出到屏幕,而保存在模式空间的未处理行不显示(常用)
-- -i :直接修改读取内容,不输出(这样会修改源文件)
-- -r : 使用扩展正则表达式(预设是基础正规表示法语法)
-- -e :直接在指令列模式上进行sed的动作编辑
-- -f : 指定一个sed脚本文件到命令行执行
1. Adress 为Sed定位
因为sed命令在没有给定的位置时,会默认处理所有行。如果想要提高工作效率,可以使用sed定位,sed编辑器便只操作 指定的文本行。以下为sed支持的几种地址类型:
1.1 通过行号匹配
-- 1.1.1 按照行号n~m
匹配
其中,n指 起始匹配行,m指 步长。例如 sed -n ‘2~5 p’ test.txt
指的是输出test.txt文件中的 第2,7,12,17...行(p
即print --"打印")
-- 1.1.2 按照行号n,m+
匹配
n指 起始匹配行,m+指向下匹配n行。例如 sed -n ‘2,5+ p’ test.txt
指的是输出test.txt文件中的 n到n+m行(共匹配m+1行)
1.2 按匹配条件匹配
即/pattern/command
形式,匹配条件通常夹在//
中间(双斜杠//
里面可以是正则表达式),例如sed -n ‘/^peaceful/ p’ test.txt
指的是输出test.txt文件中所有以peaceful为行首的行。
1.3 通过adress定位匹配
即sed -n 'addr1,addr2 p' filename
形式,addr1和addr2为两个地址,他们可以是数字, 也可以是正则表达式。
例如:sed -n '1,6 p' test.txt
匹配test.txt中的1-6行;sed -n '/^peaceful/,6+ p' test.txt
匹配test.txt中行首为peaceful的行及以下6行。
2.command为sed行使功能
- command 指命令(多个命令用
;
分隔)
注意:sed后面接的动作都要用单引号''
括住
2.1 新增 a
-- a:新增,a的后面可以接字符串,而这些字符串会在新的一行出现(目前的下一行)
eg: sed '1a peaceful' test.txt
在第1行后(也就是第2行)增加peaceful
2.2 取代c
-- c:整行取代,c的后面可以接字符串,用以取代指定行
eg: sed '1,3c peaceful' test.txt
将test.txt的1-3行用peaceful取代
2.3 删除d
-- d:删除,eg: sed '2,5d' test.txt
删除第2行到第5行
eg: sed '1,3d' test.txt
删除 test.txt的1-3行
2.4 插入i
-- i:插入,i的后面可以接字符串,而这些字符串会插入到目前的上一行
eg: sed '3i peaceful' test.txt
将会在第三行出现peaceful (注意,这里的i是command而不是👆上面的参数i)
-- a:与i
类似,后面可以接字符串,而这些字符串会会插入到目前的下一行
2.5 打印p
-- p:打印
eg: sed -n '1,3p' test.txt
2.6 数据取代s
-- s:数据取代,通常可以搭配正规表示法
eg:sed '1,20s/old/new/' test.txt
将test中第1到20行的old变成new
3.sed的应用实例
3.1以行为单位的新增/删除功能
nl /etc/passwd | sed '2,5d'
列出/etc/passwd的内容+打印行号,同时将2-5行删除
nl /etc/passwd | sed '2a drink tea'
列出/etc/passwd的内容+打印行号,同时在第三行加上“drink tea”
如果要新增好几行,可以使用\
进行新行的增加,补鸟哥的图来理解:
3.2 以行为单位的取代与显示功能
nl /etc/passwd | sed '2,5c No 2-5 number'
将/etc/passwd 2-5行的内容取代为No 2-5 number
nl /etc/passwd | sed -n '5,7p'
列出/etc/passwd 的第5-7行(不用纠结得使用head -n 7 | tail -n 3 啦~),同时,你可能会疑惑为什么这里加了参数-n
:因为不加n的话5-7行会重复输出
3.3 部分数据的搜寻并取代的功能
除了整行的处理模式之外,sed还可以用行为单位进行部分数据的搜寻并取代的功能,与vi的取代相似:sed 's/要被取代的字符串/新的字符串/g'
。这里配合着用到些正则表达式,还不懂正则表达式是什么东东的小伙伴可以从Linux - 正则表达式学习。
3.3.1 查询IP
ifconfig | grep -w inet
查询IP
ifconfig | grep -w inet | sed 's/^.*inet //g'
将IP前面的“inet+空格”部分删掉ifconfig | grep -w inet | sed 's/^.*inet //g' | sed 's/ .*$//g'
将IP前面的“inet+空格”部分删掉,同时将IP后面的一切都删掉
3.3.2 查看man_db.conf
通过cat /etc/man_db.conf | grep 'MAN'
查看文本内容
cat /etc/man_db.conf | grep 'MAN' | sed 's/^#.*$//g'
通过sed的取代功能将注释行的字符都删掉cat /etc/man_db.conf | grep 'MAN' | sed 's/^#.*$//g' | sed '/^$/d'
通过sed删除指定空白行,这里的空白行使用的是^$
小Tip总结:
- 指定字符的删除:通过
sed 's/要被删除的字符串//g'
的形式实现指定字符的删除 - 空白行的删除:通过
sed '/^$/d'
- 最后一行新增一行:通过
sed -i '$a # This is a test' filename
(-i会直接修改文件哦;$代表最后一行;a代表新增;# This is a test为新增内容)