sed编辑器

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

sed 编辑器

工具sed(stream editor, 流编辑器) 是一个批处理编辑器。常被作为管道中的过滤器。

语法:

sed 的命令行语法如下:

sed [-n] program [file-list]

sed [-n] -f program-file [file-list]

sed 工具从命令行所指定的文件或者标准输入中获取输入流,除非明确指定输出目标,否则sed 将把结果输出到标准输出。

 

参数:

program 命令行中的sed 程序。

program-file 表示一个包含了sed 程序的文件的完整路径名。

file-list sed 将要处理的普通文件的完整路径名,即sed 的输入文件。如果没有指定,则读取标准输入作为输入。

 

选项:

-f program-file 使得sed 从文件program-file 中读取程序,而不是从命令行中读取。

-i[suffix] 就地编辑文件,如果没有这个选项,sed 将输出送到标准输出。该选项使得sed 将输出送入原来的输入文件。一旦指定了后缀名suffix sed 将备份原来的文件。

-n 指示除非使用p 指令或标志来指定,否则不会将文本行复制到标准输出。sed 仅仅输出特定的行,例如那些被Print p )指令选定的行。

 

编辑器基础

sed 程序由符合如下语法的一行或多行命令构成:

[address[,address]] instruction [argument-list]

其中address 是可选的。如果省略address ,那么sed 将对输入中所有行进行处理。

instruction 是一些用于改变文本的编辑指令。address 用于选定命令中的指令instruction 进行操作的文本行。argument-list 中的参数的数目和类型取决于指令instruction 。如果想把多个sed 命令放在同一行,那么可以使用英文分号';' 来分隔这些命令。

地址

行号作为地址可以用来选择某一行。$ 表示输入中的最后一行。

正则表达式作为地址 可以用来选择那些包含与正则表达式相匹配的字符串的行。

指令之前可以有0,1,2 个地址( 行号或正则表达式 ) :如果没有指定地址,sed 选择所有的行,使得该指令对输入中所有的行进行操作;提供一个地址将使得指令作用于由该地址选择的每一行输入;提供两个地址将使得指令作用于成组的输入行。

 

指令

d 删除指令,导致sed 不输出被选择的行,并且不继续完成对该行的后续处理过程。

n 下一条指令,输出当前选择的行( 如果可以) ,然后重新读入一行并从下一条命令 开始对其进行处理。

a 追加指令,在当前选择的行之后插入一行或多行文本。如果提供了俩个地址,则在选定的每一行之后添加文本。如果没有地址,则在每一行之后添加文本。

[address[,address]] a/

text1/

text2/

….

text

除最后一行外,所有添加的文本的每一行都必须以反斜杠结尾( 反斜杠用于指代行末的换行符) 。没有以反斜杠结尾的行被视作要添加的文本的尾行。sed 总是输出所添加的文本,而不论是否在命令行中使用了-n 选项,甚至在删除被添加了文本的那一行后,被添加的文本仍会被输出。

i 插入指令,与a 命令相同,只不过是将文本添加到选定的行之前。

c 修改指令,与a i 指令用法相同,只不过是将选定的行修改为新的文本。

s 替换 指令 ,与vim 类似

[address[,address]] s/pattern/replacement-string/[g][p][w file]

replacement-string 可以包含符号& sed 将用与pattern 匹配的字符串替换& 符号。除非使用g 标志,否则s 指令将只对每个选定的行中第1 个与pattern 匹配的字符串进行替换。

全局标志g 使得sed s 指令对选定的行中匹配pattern 的非重叠字符串进行替换。

打印标志p 使得sed 将所有应用了替换操作的行输出到标准输出中。

写标志w p 标志类似,但它将输出送入file 指定的文件中。

p 打印指令,将选定的行写入标准输出,写入动作是立即发生的,并不反应后续指令的执行结果。

w file 写指令,与p 指令类似,将输出写入由file 指定的文件中。

r file 读指令,读出指定文件的内容并添加到选定的行之后。

q 退出命令,使得sed 立即结束。

 

控制结构

! 使得sed 后面与其同一行的指令作用于没有被该命令中的地址选中的每一行。3!d 删除除第3 行以外的所有行,$!p 显示除最后一行外的所有行。

{} 指令组,这组指令将作用于它前面的地址选定的行。

:label 标识sed 程序中的一个位置。label 作为跳转目标对分支指令b t 是有用的。

b [label] 无条件转移控制到label 标识的命令。如果没有label 则跳过当前行中剩余的指令并从输入中读取下一行。

t [label] 如果最近从输入中读取的行使得s 指令匹配成功,则转移到label 标识的命令。如果没有label 则跳过剩余的指令并从输入中读取下一行。

Pattern 区和Hold

sed 中有两个缓冲区。所有的命令都是工作在Pattern 区上的。Pattern 区中保存着sed 刚刚从输入中读取的行。作为临时缓冲区,Hold 区可以在操作Pattern 区中的数据时用来暂存数据。在将数据放入Hold 区之前,它的内容为空。

g hold 区中的内容复制到Pattern 区中。Pattern 区中的原来的内容将会丢失。

G 将一个换行符和Hold 区中的内容追加到Pattern 区的内容之后。

h pattern 区中的内容复制到Hold 区中。Hold 区中的原来的内容将会丢失。

H 将一个换行符和Pattern 区中的内容追加到Hold 区中的内容之后。

x 交换Pattern 区和Hold 区中的内容。

 

例子:

>sed 's/^.//t&/' new

>cat -n ind

1 #!/bin/sed -f

2 s/^.//t&/

>cat -n cleanup

1 #!/bin/sed -f

2 s/ *$//

> sed '/line/ p' new

> sed -n '/line/ p' new

> sed -n '3,6 p' new

> sed '5 q' new

> sed 's/^.//t&/' new

 

例子:

makefile 中自动产生依赖的一个例子。

 

>cat -n test_file.c

1 #include "headfile1.h"

2 #include "headfile2.h"

3 #include "headfile3.h"

4

5 void test_function(void)

6 {

7

8 }

>touch headfile{1,2,3}.h

>cat -n Makefile

1 %.d:%.c

2 $(CC) -M $(CFLAGS) $< > $@.$$$$;/

3 sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@;/

4 rm -f $@.$$$$

>make test_file.d

cc -M test_file.c > test_file.d.$$;/

sed 's,/(test_file/)/.o[ :]*,/1.o test_file.d : ,g' < test_file.d.$$ > test_file.d;/

rm -f test_file.d.$$

>cat test_file.d

test_file.o test_file.d : test_file.c headfile1.h headfile2.h headfile3.h


------

一点分析:

%.d: %.c

$(CC) -M $(CPPFLAGS) $< > $@.$$$$; /

sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@; /

rm -f $@.$$$$

使用c 编译器自动产生依赖(-M) ,依赖文件($<) 的依赖关系(.c 文件和其头文件的依赖关系); 依赖关系输出到指定临时文件(> $@.$$$$) ,文件名为目标(.d 目标文件).PID ,‘$$$$’PID 号,在shell 中‘$$’ 表示PID ,但是这里需要对其转义。

sed 依照给定的程序代码('s,/($*/)/.o[ :]*,/1.o $@ : ,g') ,对输入流进行处理(< $@.$$$$) ,并将处理结果输出(> $@)

's,/($*/)/.o[ :]*,/1.o $@ : ,g'

','

sed 替换命令格式中的分隔符,典型分隔符为'/'

s’

's'sed 替换命令

'/($*/)/.o[ :]*'

'/($*/)' 正则表达式,$* 表示make 模式规则中的径,'/''('')' 转义,括号在这里的作用是将正则表达式括起来,正则表达式并不匹配转义的括号,所以同'$*' ,就是匹配make 模式规则中的径。

'/.o' '/''.' 的转义,匹配'.o' 字符串。

'[ :]*' 中括号定义字符类,星号匹配0 个或多个星号前面匹配的字符。匹配0 个或多个空格,匹配0 个或多':'

所以整个表达式匹配,模式规则得到的径后面跟'.o' 再跟0 个或多个空格,或模式规则得到的径后面跟'.o' 再跟0 个或多个':'

'/1.o $@ : ,g'

'/1' 搜索字符串中,括号正则表达式如/(xxx/) 与不带转义圆括号的正则表达式匹配的字符串相同(xxx) ;在替换字符串中,转义数字/n 代表搜索字符串的第n 个括号正则表达式/( 开始匹配的字符串。所以这里的'/1' 就代表搜索得到的径。

'$@' 代表,make 规则描述中的目标(.d 文件)

'g' 全局替换,针对一行中有多个匹配项。而由于sed 处理的程序没有给出针对输入的处理地址,只给出了处理指令(s ,替换) ,所以默认的是对所有输入行进行查找替换。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章