Sed is a stream editor. A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline). While in some ways similar to an editor which permits scripted edits (such as ed), sed works by making only one pass over the input(s), and is consequently more efficient. But it is sed’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.
sed选项
调用sed命令有两种形式:sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
其中option是可选的,常用的option有如下几种:
选项 | 功能 |
---|---|
–version | 打印版本和版权信息 |
–help | 打印命令的概括信息,并显示bug列表的地址 |
-n,–quiet,–silent | 默认情况下,所有来自stdin的内容都会被输出到屏幕上。这些参数禁止自动输出,只有使用 p命令时才会输出 |
-e script,–expression=script | 直接在指令列模式上进行 sed 的动作编辑 |
-f script-file,–file=script-file | 将 sed 的命令写在script文件内, 当处理输入时可以执行script内的sed命令 |
If no -e, -f, –expression, or –file options are given on the command-line, then the first non-option argument on the command line is taken to be the script to be executed.
If any command-line parameters remain after processing the above, these parameters are interpreted as the names of input files to be processed. A file name of ‘-’ refers to the standard input stream. The standard input will be processed if no file names are specified.
sed命令
下面是一些常用的命令:
命令 | 功能 |
---|---|
a | 新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)。在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行 |
c | 取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用”\”续行 |
d | 删除,删除 Pattern space,所以 d 后面通常不接任何咚咚 |
i | 插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)。在当前行之前插入文本。多行时除最后一行外,每行末尾需用”\”续行 |
p | 打印,打印pattern space到标准输出。通常 p 会与参数 -n 一起使用 |
s | 替换,用一个字符串替换另一个,可与正则表达式一起使用。s/re/string,用string替换正则表达式re。 |
q | 结束或退出sed |
n | 如果自动打印未启用,打印pattern space,然后读取下一个输入行,并从下一条命令而不是第一条命令开始对其的处理 |
# | 把注释扩展到下一个换行符以前 |
r | 从文件中读取输入行 |
g | 把暂存缓冲区里的内容复制到模式空间,覆盖原有的内容。获得内存缓冲区的内容,并替代当前模板块中的文本。在行内进行全局替换 |
下面是一些不太常用的命令:
命令 | 功能 |
---|---|
h | 把模式空间里的内容复制到暂存缓冲区 |
H | 把模式空间里的内容追加到暂存缓冲区 |
G | 把暂存缓冲区的内容追加到模式空间里,追加在原有内容的后面 |
l | 列出非打印字符 |
! | 对所选行以外的所有行应用命令。表示后面的命令对所有没有被选定的行发生作用。 |
w | 将所选的行写入文件,file写并追加模板块到file末尾 |
x | 交换暂存缓冲区与模式空间的内容 |
y | 将字符替换为另一字符(不能对正则表达式使用y命令) |
b lable | 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。 |
D | 删除模板块的第一行。 |
N | 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。 |
P | 打印模板块的第一行。 |
t labelif | 分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。 |
T label | 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。 |
W file | 写并追加模板块的第一行到file末尾。 |
= | 打印当前行号码。 |
正则表达式元字符
与grep一样,sed也支持特殊元字符,来进行模式查找、替换。不同的是,sed使用的正则表达式是括在斜杠线”/“之间的模式。
如果要把正则表达式分隔符”/“改为另一个字符,比如o,只要在这个字符前加一个反斜线,在字符后跟上正则表达式,再跟上这个字符即可。例如:sed -n ‘\o^Myop’ datafile
元字符 | 功能 | 示例 |
---|---|---|
^ | 行首定位符 | /^my/ 匹配所有以my开头的行 |
$ | 行尾定位符 | /my$/ 匹配所有以my结尾的行 |
. | 匹配除换行符以外的单个字符 | /m..y/ 匹配包含字母m,后跟两个任意字符,再跟字母y的行 |
* | 匹配零个或多个前导字符 | /my*/ 匹配包含字母m,后跟零个或多个y字母的行 |
[] | 匹配指定字符组内的任一字符 | /[Mm]y/ 匹配包含My或my的行 |
[^] | 匹配不在指定字符组内的任一字符 | /[^Mm]y/ 匹配包含y,但y之前的那个字符不是M或m的行 |
(..) | 保存已匹配的字符 | 1,20s/(you)self/\1r/ 标记元字符之间的模式,并将其保存为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。此例中,对第1到第20行进行处理,you被保存为标签1,如果发现youself,则替换为your。 |
& | 保存查找串以便在替换串中引用 | s/my/&/ 符号&代表查找串。my将被替换为my |
\< | 词首定位符 | /\<my/ 匹配包含以my开头的单词的行 |
> | 词尾定位符 | /my>/ 匹配包含以my结尾的单词的行 |
x{m} | 连续m个x | /9{5}/ 匹配包含连续5个9的行 |
x{m,} | 至少m个x | /9{5,}/ 匹配包含至少连续5个9的行 |
x{m,n} | 至少m个,但不超过n个x | /9{5,7}/ 匹配包含连续5到7个9的行 |
命令示例
以官方文档的大纲为例:
cat filename
Execution Cycle: How sed works
Addresses: Selecting lines with sed
Regular Expressions: Overview of regular expression syntax
Common Commands: Often used commands
The “s” Command: sed’s Swiss Army Knife
Other Commands: Less frequently used commands
Programming Commands: Commands for sed gurus
Extended Commands: Commands specific of GNU sed
Escapes: Specifying special characters
a命令
a 命令是追加命令,追加将添加新文本到文件中当前行(即读入模式缓冲区中的行)的后面。所追加的文本行位于sed命令的下方另起一行。如果要追加的内容超过一行,则每一行都必须以反斜线结束,最后一行除外。最后一行将以引号和文件名结束。#本例命令部分中的1表示第一行,同样的第二行写成2,第一行到第三行写成`1,3`,用`$`表示最后一行,比如`2,$`表示第二行到最后一行中间所有的行(包含第二行和最后一行)。
#第一行后添加
sed '1a Hi,welcome to sed!' filename
#最后一行后添加内容,使用换行符\n
sed '$a Hi,welcome to sed!\
Do u like it?' filename
#在第一行到最后一行后添加内容,会在每一行下添加
sed '1,$a Hi,welcome to sed!' filename
#在包含"Programming"字符串的行的后面添加内容
sed '/Programming/a Hi,welcome to sed!' filename
#使用正则表达式匹配行,`^The.*Knife$`表示以sed's开头,以Knife结尾的行,则可以匹配到文件的"The "s" Command: sed's Swiss Army Knife
",所以在该行后面增加了"Hi,welcome to sed!"。
sed '/^The.*Knife$/a \Hi,welcome to sed!' filename
i命令
i命令使用方法和a命令一样的,只不过是在匹配的行的前面插入,直接将上面a命令的示例的a替换成i即可。
c命令
sed使用该命令将已有文本修改成新的文本。
#本例表示将最后一行替换 |
d命令
命令d用于删除输入行。sed先将输入行从文件复制到模式空间里,然后对该行执行sed命令,最后将模式空间里的内容显示在屏幕上。如果发出的是命令d,当前模式空间里的输入行会被删除,不被显示。
#删除第一行中的内容 |
p命令
命令p用于显示模式空间的内容。默认情况下,sed把输入行打印在屏幕上,选项-n用于取消默认的打印操作。当选项-n和命令p同时出现时,sed可打印选定的内容。
#默认情况下,sed把所有输入行都打印在标准输出上。如果某行匹配模式my,p命令将把该行另外打印一遍。 |
s命令
实际运用中s命令式最常使用到的。
#命令末端的g表示在行内进行全局替换,也就是说如果某行出现多个Commands,所有的Commands都被替换为cmds |
e选项
e是编辑命令,用于sed执行多个编辑任务的情况下。在下一行开始编辑前,所有的编辑动作将应用到模式缓冲区中的行上。
#选项-e用于进行多重编辑。第一重编辑删除第1-3行。第二重编辑将出现的所有My替换为Your。因为是逐行进行这两项编辑(即这两个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果。 |
r命令
r命令是读命令。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置上。
#如果在文件filename的某一行匹配到模式My,就在该行后读入文件introduce.txt的内容。如果出现Commands的行不止一行,则在出现Commands的各行后都读入introduce.txt文件的内容。 |
w命令
sed -n '/Common/w filename2' filename |
n命令
sed使用该命令获取输入文件的下一行,并将其读入到模式缓冲区中,任何sed命令都将应用到匹配行紧接着的下一行上。
# 如果需要使用多条命令,或者需要在某个地址范围内嵌套地址,就必须用花括号将命令括起来,每行只写一条命令,或这用分号分割同一行中的多条命令。 |
y命令
该命令与UNIX/Linux中的tr命令类似,字符按照一对一的方式从左到右进行转换。例如,y/abc/ABC/将把所有小写的a转换成A,小写的b转换成B,小写的c转换成C。
#将1到20行内,所有的小写hrwang转换成大写,将1转换成^,将2转换成$。 |
q命令
q命令将导致sed程序退出,不再进行其它的处理。
sed '/hrwang/{s/hrwang/HRWANG/;q;}' filename |
h命令和g命令
#cat datafile |
#通过上面两条命令,你会发现h会把原来暂存缓冲区的内容清除,只保存最近一次执行h时保存进去的模式空间的内容。而H命令则把每次匹配hrwnag的行都追加保存在暂存缓冲区。 |
sed脚本
sed脚本就是写在文件中的一列sed命令。脚本中,要求命令的末尾不能有任何多余的空格或文本。如果在一行中有多个命令,要用分号分隔。执行脚本时,sed先将输入文件中第一行复制到模式缓冲区,然后对其执行脚本中所有的命令。每一行处理完毕后,sed再复制文件中下一行到模式缓冲区,对其执行脚本中所有命令。使用sed脚本时,不再用引号来确保sed命令不被shell解释。例如sed脚本script:
#handle datafile |
#sed -f script datafile |