一.sed脚本编程的方法论

1.         在着手做之前要弄清楚想做什么。

2.         明确地描述处理的过程。

3.         在提交最终的改变之前反复测试这个过程。

1检测脚本最好的方式,是使用不同的输入样本进行测试并观察结果。

二.sed 的工作方式(原理)

sed 命令按顺序逐行将文件读入到内存中。它一次处理一行内容,以行为单位。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。期间还可以使用hold space的内存缓冲空间作为二级缓冲处理。默认输出是将每一行的内容输出到屏幕上(标准输出)

其中两个重要的因素:第一,输出可以被重定向到另一文件中,以保存变化;第二,源文件(默认地)保持不被修改。sed 默认读取整个文件并对其中的每一行进行修改。不过,可以按需要将操作限制在指定的行上。

三.命令语法

sed [options] '{command}' [filename]

1.         选项与参数:[-nefri]

-n  :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 数据一般都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。

-e :直接在命令列模式上进行 sed 的动作编辑;

-f 直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename sed 动作;

-r  sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)

-i  :直接修改读取的文件内容,而不是由萤幕输出。

2.         命令说明:

sed '[address]function'

首先地址是可选的,地址范围(address)可以用:

 

              表示所有行,命令应用于每一行。

例:d           删除所有行。

n1              数字构成,单个数字(n1)表示单独的一行。

例:1d          删除第一行。

n1,[n2]         用逗号分隔( n1,[n2] )的两个行数表示以这两行为起止的行的范围。

例:10,20d      删除1020行(包括第10和第20行)。

10,d            删除10行以上的所有行。

$               寻址符号($)表示待处理文本的最后一行,与正则表达式中$(单个行结尾)          不同。

 

例:$d          删除最后一行。

 

!               地址后跟 “!” 表示命令匹配该地址以外的所有行。

例:10!d        删除除了第10行以外的所有行。

RE              正则表达式作为地址提供,命令只影响与正则表达式匹配的行,正则表达式          必须封闭在斜杠”/“

例:/^$/d       删除所有空行。

常用动作有:

a :新增,a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)

例:sed  '2a string'  filename

c  :取代,c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!

例:sed  '2c string'  filename

d :删除,d 后面通常不接任何字符;

例:sed  '2d'  filename

i :插入,i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行).

例:sed  '2i'  filename

p :打印/列出,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行。

例:sed  '2p'  filename

r从文件中读取,后面接文件名称,一个脚本最多打开10个文件,文件不存在命令不会报错。

格式为:[line-address]r file              //操作单行,不能处理范围内的行。

例:sed '/test/r filename1' filename2       //filename1的内容被读取出来,显示在匹配的与test匹配的行的后面。

w : 将模式空间中内容写到文件中,追加到文件中,不存在则创建。

格式为:[address]w file                    //对行没有限制,单行,多行都可以处理。

l :  列表命令用于显示模式空间的内容,将非打印的字符显示为两个数字的ASCII代码。其功能类似于vi 中的列表命令(:l 

例:sed  -n l filename

y转换命令是特有的,按位置将字符串中abc每个字符,都转换为xyz中的等价字符,在该地址范围内的所有的a 都被替换成了 x ,而不管它后面有没有b

格式为:
[address]y/abc/xyz/

例:sed y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ

s :替换,可以直接进行取代,通常这个 s 的动作可以搭配。

例:sed  's/old-value/new-value/g' filename

说明:将”old-value”字符替为”new-value”字符

详细用法:

[address]s/pattern/replacement/flags

flags是:

n     1-512之间的一个数字,表示文本模式中指定模式n次出现的情况进行替换。

#cat quanju

1hang-1hang-1hang

2hang-2hang-2hang

例:
sed ‘s/hang/@/2’ quanju

1hang-1@-1hang

2hang-2@-2hang

说明:替换每一行中第
2
个匹配的字符串。

g    对模式空间的所有出现的情况进行全局更改。而没有g通常只有第一次出现的情况被替换。

例:sed ‘s/hang/@/g’ quanju

1@-1@-1@

2@-2@-2@

p    (小写p)打印模式空间的内容。

w      (小写w)file 将模式空间的内容写到文件file中。

3.         命令行上3种方式书写多重指令

a)         分号分隔方式;

例: sed 's/old1/new1/; s/old2/new2/; s/old3/new3/' filename

b)         每个指令前加 -e 参数;

例: sed -e 's/old1/new1/' -e 's/old2/new2/' filename

c)         bourne shell的分行指令功能;

单引号后RETURN,出现多行输入提示符(>).    

说明:

Csh中不能使用,Csh中每个指令结尾使用分号,使用反斜杠(\)作为每一行的结束。

Bourne shell兼容的shell,如:ksh,bash,pdks,zsh则可以使用(' " ( { \)进行分行指令。

1# sed '

     > s/old1/new1/

     > s/old2/new2/

     > s/old3/new3/' filename