sed命令
名称
sed - stream editor(行编辑器),与grep、awk合成文本处理三剑客
格式
sed [option]… {script}… [input-file]
描述
sed有两个特殊的存储空间,pattern space(模式空间)和 hold space(保持空间),每次从input-file中只读取一行文本数据匹配{script}进行处理后保存在模式中,直到最后处理完所有行的数据,参考[option]进行相应的统一输出。模式空间与保持空间可以在{script}中通过相关的编辑命令来回调换数据完成一些特殊的高级操作。
[option]
-n input-file处理完成后,不输出模式空间的内容。
-e {script}… 通过-e选项可以添加多个{script}对行数据进行多次匹配处理
-f {script-file} 把{script}按照每行一个的格式写在文本文件中,调用这个文件进行匹配处理
-r {script}可以使用扩展正则表达式
-i 不经过模式空间,直接在源文件中匹配修改(慎用)
{script}
{script} --> 地址定界编辑命令
-
地址定界
1、空地址全文匹配,相当于vim替换命令中的全文定界符%
2、单地址
# 指定行 /pattern/ 被模式匹配的每一行
3、地址范围
#,# #,+# 指定行到指定行后面#行的范围 #,/pat1/ 指定行到被/pat1/匹配到的行之间 /pat1/,/pat2/ 被/pat1/匹配的行与被/pat2/匹配到的行之间
4、步进 ~
如:1~2 表示奇数;2~2表示偶数
-
编辑命令
d 删除 p 打印 w /PATH/TO/SOMEFILE 被模式匹配到的行另存到指定文件 r /PATH/FROM/SOMEFILE 从指定文件中读取内容追加到被模式匹配到的行后面,合并文件 a TEXT 追加指定的TEXT到被模式匹配到的行后面 i TEXT 插入指定的TEXT到被模式匹配到的行前面 = 在被匹配到的行前添加一行打印行号 ! 条件取反(地址定界!编辑命令) s/// 替换命令,使用方法同vim,可以自行指定分隔符,常用的有@@@,### 替换标志:g 全局替换 w /PATH/TO/SOMEFILE 将替换后的那一行的内容保存到指定文件 p 打印被替换后的内容
-
高级编辑命令
h 将模式空间的内容(所有)覆盖至保持空间 H 将模式空间的内容(所有)追加至保持空间 g 将保持空间的内容(所有)覆盖到模式空间 G 将保持空间的内容(所有)追加至模式空间 x 将模式空间的内容(所有)与保持空间的内容(所有)互换 n 读取被模式匹配行的下一行覆盖至模式空间 N 读取被模式匹配行的下一行追加至模式空间(编辑命令操作时,两行会当作一个整体进行处理) ps:n和N因为已经读取了下一行,所以下次读取会从下下一行开始 d 删除模式空间的行(匹配此编辑命令的单行) D 删除多行模式空间中的所有行(似乎与n,N有关)
逻辑
测试条件:创建一个文本文件,将1-7分行写入文件
待处理文本按行逐次读取至sed的模式空间中,匹配{script}处理后输出至屏幕(也有可能不打印输出,-n选项),
本行处理完成后清空模式空间(如果没有保存到保持空间的编辑命令)进行下一行的读取跟处理。
这个过程中分析其逻辑稍微感觉到诧异:
1、没有-n选项的情况下,每一行在模式空间中先进行处理,再将处理后的结果打印输出,默认会将结果打印一遍,如果编辑命令中加了p,会发现一行被打印了两遍,比如 sed “s/2/20/g;p” input-file,会发现所有的行出现两边,包括替换成20 的行。
2、上面的例子中,如果加了-n,则出现所有行的打印了一遍,匹配到的行打印出来的是替换后的结果,这说明不加-n只是把打印的模式空间的内容执行两次p,而不是对原始数据执行一次p处理,然后对匹配的结果再进行一次p处理
3、sed “3N;p” input-file 会发现打印出来的是3、4、3、4、5、5,而不是3、4、3、4、4、4,说明N将第四行提前读入模式空间,处理完成后,下次读取会跳过第四行
4、sed -n “3n;p” input-file 也支持上述的逻辑,但是下面的例子很让人诧异,不知道是为什么
5、sed “3n;p” input-file 发现只有3被打印了一遍,其他都是两遍,想不明白为什么
补充:想明白了上面第5条的逻辑,“地址定界”3与“编辑命令”n是一个整体,不包含分号后面其他的编辑操作