sed是一种能够执行与VI相同功能的编辑器,特点如下:不提供交互式的使用方式,只能在命令行输入命令、指定文件名,并在屏幕上查看输出;另外它没有破坏性,不会修改原文件,所有修改在模式空间内部进行,结果打印到屏幕,除非使用shell重定向来保存输出结果。
 
1. sed如何工作:
sed逐行处理输入文件,并将输出结果发送到屏幕。具体过程:
将当前行读入到模式空间(一个临时缓冲区);
在该行上执行命令;
将结果发送到屏幕上(除非取消了缺省打印,或者之前的处理是将行删除);
将行从模式空间删除;
读入输入的下一行。
 
如果是将多个sed写入到脚本,则处理过程如下:
将输入文件中的第一行拷贝到模式空间;
执行脚本中的所有命令;
拷贝下一行到模式空间,执行脚本所有命令,直到处理完全部输入。

2. sed命令与选项
 
2.1 命令格式
sed命令告诉sed对文件中的行做什么操作,具体操作可以包含打印、删除、修改等。格式如下:
     sed 'command' filename(s)
 
命令command中可以指定地址,如果指定了地址,则根据命令处理地址对应的行;否则sed就会处理输入的每一行。
地址可以是数字、正则表达式或者两者的组合,规则如下:
地址如果是一个数字,则表示一个行号;
如果给出的是逗号分隔的2个行号,则表示要处理的地址就是两行之间的范围,包括这两行;
如果给定的是正则表达式,则处理匹配该表达式的所有行;
美元符号$代表输入文件的最后一行;
范围可以包含数字、正则表达式、或者两者的组合。
 
2.2 常用命令和举例(一)

(1) 打印命令:p
gaolu@gaolu-desktop:~$ cat datafile
NAME      SCORE   
William    100
Suan       90
Jim        80
Lucy       100
 
gaolu@gaolu-desktop:~$ sed '/100/p' datafile  打印包含模式100的行
NAME      SCORE   
William    100
William    100
Suan       90
Jim        80
Lucy       100
Lucy       100
gaolu@gaolu-desktop:~$
 
缺省情况下,sed会将所有行打印到标准输出上。对于匹配到模式100的行,sed会另外将其打印一次。使用选项-n可以关闭缺省打印:
gaolu@gaolu-desktop:~$ sed -n '/100/p' datafile
William    100
Lucy       100
gaolu@gaolu-desktop:~$
 
(2)删除命令:d
gaolu@gaolu-desktop:~$ cat datafile
NAME      SCORE   
William    100
Suan       90
Jim        80
Lucy       100
 
gaolu@gaolu-desktop:~$ sed '3d' datafile  删除第三行
NAME      SCORE   
William    100
Jim        80
Lucy       100
gaolu@gaolu-desktop:~$
缺省情况下,其他行都被直接打印到屏幕。
 
gaolu@gaolu-desktop:~$ sed '3,$d' datafile  删除第三行到最后一行
NAME      SCORE   
William    100
gaolu@gaolu-desktop:~$

(3)替换命令:s
gaolu@gaolu-desktop:~$ cat datafile
NAME      SCORE   
William    100
Suan       90
Jim        80
Lucy       100
 
gaolu@gaolu-desktop:~$ sed 's/100/good/g' datafile
NAME      SCORE   
William    good
Suan       90
Jim        80
Lucy       good
gaolu@gaolu-desktop:~$
说明:g表示在行内进行全局替换,即如果行里面出现多个100,则全部替换为good;否则只讲第一个100替换为good.
 
gaolu@gaolu-desktop:~$ sed -n 's/100/good/gp' datafile
William    good
Lucy       good
gaolu@gaolu-desktop:~$
关闭缺省打印,只打印发生替换的行。
 
gaolu@gaolu-desktop:~$ cat datafile
NAME      SCORE   
William    100
Suan       90
Jim        80
Lucy       100
Tom        9
gaolu@gaolu-desktop:~$ sed 's/[0-9][0-9]$/&.5/' datafile 
&用在s命令的替换串中时,用于代表查找串中匹配的内容。即有2个数字结尾的行,数字后+。5
如果需要表示“与”符号字面含义,需要使用转义字符。
NAME      SCORE   
William    100.5
Suan       90.5
Jim        80.5
Lucy       100.5
Tom        9
gaolu@gaolu-desktop:~$
 
gaolu@gaolu-desktop:~$ sed 's/\(NAME\)/ENGLISH_\1/' datafile
ENGLISH_NAME      SCORE   
William    100
Suan       90
Jim        80
Lucy       100
Tom        9
gaolu@gaolu-desktop:~$
元字符\(..\)用括进的模式作为标签1保存在特殊寄存器中,此后可以使用\1来引用它。做多可以定义9个标签。
这里NAME---------->\1,而替换NAME的是ENGLISH_NAME.
 
(4)指定行范围:逗号
gaolu@gaolu-desktop:~$ sed -n '3,/Lucy/p' datafile  打印从第三行开始,到包含模式Lucy的行
Suan       90
Jim        80
Lucy       100
 
gaolu@gaolu-desktop:~$ sed -n '/Lucy/,3p' datafile   打印从包含模式Lucy的行开始,到第三行,由于模式Lucy已经处于第五行,这里只打印第五行
Lucy       100
gaolu@gaolu-desktop:~$

gaolu@gaolu-desktop:~$ sed -n '/Lucy/,/William/p' datafile
Lucy       100
Tom        9
gaolu@gaolu-desktop:~$
打印从包含模式Lucy的行开始,到包含模式William的行。如果模式William先出现,打印从模式Lucy所在行开始,到下一个包含模式William的行。如果后面没有,则打印到文件末尾。
 
(5)多重编辑:e命令
gaolu@gaolu-desktop:~$ sed -e '2d' -e 's/Tom/tom/' datafile
NAME      SCORE   
Suan       90
Jim        80
Lucy       100
tom        9
gaolu@gaolu-desktop:~$
这里需要注意的是多重命令都是在模式空间的当前行上面进行,命令之间的前后顺序不同可能会影响到编辑的结果。

(6)读文件:r命令
gaolu@gaolu-desktop:~$ cat newfile
-----------------------------------------
                                       
       william is no 1       
-----------------------------------------
gaolu@gaolu-desktop:~$ sed '/William/r newfile' datafile  在所有包含模式William的行后面,都读入文件newfile的内容
NAME      SCORE   
William    100
-----------------------------------------
                                       
       william is no 1       
-----------------------------------------
Suan       90
Jim        80
Lucy       100
Tom        9
gaolu@gaolu-desktop:~$
要睡觉了,先总结到此,后面sed的其他命令比较多,也比这里列出的要复杂一些。比如关于模式空间的H,h、暂存缓冲区的G,g、写文件、追加、插入、交换、n命令以及!等等。后面再看看简单的脚本编程。