sed工具全称为流式编辑器,它可以被使用作为行过滤器(顾名思义sed是按照行查找进行操作的),它的工作原理可以描述为:把前一个程序的输出引入到sed的输入,经过一系列编辑命令转换为另外一种格式输出。(形象的解释如下图所示,模式空间会在后面单独提出)
以前学习到grep默认是在Basic模式下工作,这里的sed工具如grep一般,也是默认在Basic模式下工作,sed也支持正则表达式的使用,使用正则表达式是在"/"之间的模式。(当然这里的分隔符不是非"/"不可,也各可以自己定义)
1.^:行首定位符(如/^aa/匹配以aa开头的行)
2.$:行尾定位符(如/aa$/匹配以aa结尾的行)
3. .:匹配除换行符以外的单个字符(当然.. 就表示匹配两个字符了)
......(还有很多可以查看上一篇的grep的使用,有详细的介绍正则表达式的构成)
下面就以例子来介绍sed的使用。
1.语法:
sed编辑命令的基本格式为:/pattern/action/(其中pattern为正则表达式,action是使用的编辑操作)
这个操作可以比较形象的解释为:通过sed一行一行的读出待处理文件,如果某一行与pattern匹配,则执行相应的action,如果一条命令没有pattern而只用action,这个action将作用于待处理文件的每一行。
这个例子中的action为'3p',所以执行后的结果就是讲第三行打印了出来。(如若不懂为何打出来很多条文本,请看步骤2 的介绍)
2.操作
/pattern/p:打印匹配pattern的行(这个命令会连同原文件的内容和处理结果一同输入到显示器上,若用户只想查看操作之后的结果,添加上-n选项即可。(例子如下)
很明显可以验证上面的原理。
sed /pattern/a+新的字符串:在匹配到pattern后一行添加新的字符串
sed /pattern/i+新的字符串:在匹配到pattern前一行添加新的字符串
sed /pattern/d:删除匹配pattern的行(sed命令你会修改原文件,删除命令只表示某些行不打印输出,而不是从源文件中删除)
sed /pattern/s//:s为查找并替换命令
(1)/pattern/s/pattern1/pattern2/:查找符合pattern的行,将该行第一个匹配pattern1 的字符串替换为pattern2
(2)/pattern/s/pattern1/pattern2/g:查找符合pattern的行,将该行所有匹配pattern1 的字符串替换为pattern2
这个例子中的第一个操作就是将文本全部批量化注释(使用位置限定符^,匹配到所有行),而第二个操作则是匹配到printf行将所有已printf开头的注释掉。
第一个命令是匹配到该行是a的第一个字母,使用~a~替换它,第二个命令则是替换该行所有的a.第三个命令中的&符号作用是查找字符串,作用和~a~一样。
上面的例子则实现了在文本中插入空行,两种解决办法,(1)匹配行尾加以换行符
(2)匹配行首加以换行符
上面步骤大体是按照增删查改来介绍,下面再补充几条命令:
(1)c\:用该符号后面的新文本替换当前文本行中的文本。
(2)l:列出非打印字符
(3)p:打印行
(4)n:读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理
(5)q:结束或退出sed
(6)g:在行内进行全局的替换
(7)y:经字符替换为另一字符(注意不能对正则表达式使用该命令)
(8)!:对所选行以外的所有行使用该命令
3.选项
-n:只显示出修改后的结果
-e:允许多项编辑
-i:允许修改原文件
使用sed工具来实现1到100的所有数的和
首先用seq工具生成1-100的序列,然后通过管道将数据传给sed工具进行操作(实现如下)
很明显,生成了100个序列,那么要计算所有数的和的话就先累加所有数,使用tr命令将换行符替换为+号
但我们又发现最后一项多了一个符号,所以在利用管道传给计算器bc之前先将最后一项做处理,利用sed工具将最后一行的+替换为换行符即可,最终结果就如上图所示。
在了解了sed工具的基本使用之后,现在来学习文章刚开始提到的模式空间(pattern space)。
sed工作原理是将处理的行读入模式空间,每次执行sed命令后,将会把pattern space中的内容输出后清空。最后一条一条的进行相同步骤处理,直到文本执行完毕。(可以对照文章开头的图进行理解)
一般情况下,数据的流式处理只会使用模式空间,但是在实现某些特殊要求的时候会用到保持空间(hold space),换句话说,如果不显式的使用一些高级命令的话,保持空间一般都处在闲置状态。当然,这里可以将保持空间理解为一个仓库,用来暂存数据。下面就介绍一些高级命令。
+g:将保持空间的内容拷贝到模式空间中,原模式空间的内容被清除
+G:将保持空间中的内容追加到模式空间的内容之后
+h:将模式空间里的值拷贝到保持空间里,原保持空间里的内容被清除
+H:将模式空间里的内容追加到保持空间 的内容之后
+d:删除pattern中的所有行,并读入下一行到pattern中
+x:交换保持空间和模式空间的内容
以下为实践验证命令的例子:
(1)在文件aa中添加空行,这里我们使用+G命令,即将保持空间里的内容追加到模式空间的内容之后,在没有进行任何操作之前,我们可以默认保持空间中就是一个空行,这样一来,就等于是在模式空间的内容后面添加一个空行。
(2)倒着打印出aa文件里的所有行,一般使用的命令为tac,结果如下图第一部分所示,那使用sed命令怎么来实现呢?(思路如下图所示)
也就是第二部分使用的命令喽!
(3)打印匹配pattern的一行,主要思路:先逐行匹配到pattern,匹配到后将模式空间里的内容拷贝到保持空间里,最后匹配到行为的时候麻将先前拷贝到保持空间中的内容追加到模式空间中。
(4)实现1到100的总和,主要思路是:先将seq生成的序列通过管道传给sed工具,接下来,利用sed行匹配的的特性将模式空间中的内容追加到保持空间中,然后交换两个空间中的内容并用+替换换行符(这个时候我们可以看看效果)
还能明显1前面多了一个+,所以最后在添加命令去掉1前面的+部分(最终实现如下)。