1 基本概念
2 sed选项
3 定址表达式
4 sed常用命令
5 总结
学习sed的过程中,推荐使用"sedsed"调试工具,这对于分析sed处理过程以及pattern space、hold space有很大帮助。
1.基本概念sed是一个流式编辑器程序,它读取输入流(可以是文件、标准输入)的每一行放进模式空间(pattern space),同时将此行行号通过sed行号计数器记录在内存中,然后对模式空间中的行进行模式匹配,如果能匹配上则使用sed程序内部的命令进行处理,处理结束后,从模式空间中输出(默认)出去,并清空模式空间,随后再从输入流中读取下一行到模式空间中进行相同的操作,直到输入流中的所有行都处理完成。由此可见,sed是一个循环一个循环处理内容的。
这是sed的一个循环的过程:
读取输入流的一行到模式空间。
对模式空间中的内容进行匹配和处理。
自动输出模式空间内容。
清空模式空间内容。
读取输入流的下一行到模式空间。
上述整个循环过程中,第2步是我们写sed命令所修改的地方,其余的几个步骤,通过命令行无法改变。但是,sed有几个命令和选项能改变第3、4步的行为,使其输出总是输出空内容或无法清空模式空间。
sed程序的语法格式为:
sed OPTIONS SCRIPT INPUT_STREAM
其中SCRIPT部分就是所谓的sed脚本,它是sed内部命令的集合,sed中的命令有些奇特,它包含行匹配以及要执行的命令。格式为ADDR1[,ADDR2]cmd_list。例如,要对第2行执行删除命令,其命令为sed 2d filename,只输出第4行到6行,其命令为sed -n 4,6p。
sed的内部命令非常多,但既然"花拳绣腿篇",当然只介绍些入门的东西。具体的行匹配方法、有哪些命令以及哪些选项稍后解释。现在的重点是sed中的循环过程。既然SCRIPT是命令的集合,于是上面的循环过程可以修改为如下:
读取输入流的一行到模式空间。
对模式空间中内容执行SCRIPT。(包括上面示例中的"2d"和"4,6p")
读取输入流的下一行到模式空间。
对模式空间中内容执行SCRIPT。
其中SCRIPT部分包含了sed命令行中的内部命令,还包括两个特殊动作:自动输出和清空模式空间内容。这两个动作是一定会执行的,只不过有些时候通过某些命令可以使其输出空内容、使其清空不了模式空间。
如果使用编程结构来描述,则大致过程如下:
for ((line=1;line<=last_line_num;++line))
do
read $line to pattern_space;
while pattern_space is not null
do
execute cmd1 in SCRIPT;
execute cmd2 in SCRIPT;
execute cmd3 in SCRIPT;
……
auto_print;
remove_pattern_space;
done
done
其中while循环执行的正是SCRIPT中的所有命令,只不过一般情况下,while循环只执行一轮就退出并进入外层的for循环。于是,外层的for循环称之为"sed循环",内层的while循环称之为"SCRIPT"循环。所以,for循环只包含了两个动作:读取下一行和执行SCRIPT循环。
其实while循环中是有continue、break甚至是exit的,分别表示回到SCRIPT的顶端(即进入下一个SCRIPT循环)、退出当前SCRIPT循环回到外层sed循环以及退出整个sed循环。显然,这不是"花拳绣腿"的内容。
最后,说明下sed命令行如何书写,其实就是写SCRIPT部分,这部分的写法比较灵活,大致有以下几种:
# 一行式。多个命令使用分号分隔
sed Address{cmd1;cmd2;cmd3...}
# 多个表达式时,可以使用"-e"选项,也可以不用,但使用分号分隔
sed Address1{cmd1;cmd2;cmd3};Address2{cmd1;cmd2;cmd3}...
sed -e 'Address1{cmd1;cmd2;cmd3}' -e 'Address2{cmd1;cmd2;cmd3}' ...
# 分行写时
sed Address1{
cmd1
cmd2
cmd3
}
Address2{
cmd1
cmd2
cmd3
}
如果是写在文件中,即sed脚本,以文件名为a.sed为例。
#!/usr/bin/sed -f
#注释行
Address1{cmd1;cmd2...}
Address2{cmd1;cmd2...}
......
有了以上基本的大纲性知识,理解和深入sed机制就简单多了。
2.sed选项sed选项不算多,能用到的更没几个。
sed OPTIONS SCRIPT INPUT_STREAM
可能用到的几个选项: