sed实例精解--例说sed完整版

例说sed正则表达式


sedstream editorvim

流线型,非交互式的编辑器。它每次只处理一行文件并把输出打印到屏幕上。缓存

Pattern space: 模式空间即存放当前正在处理的行的缓存空间。 一旦处理工做完成,sed就会把结果输出到屏幕,而后清空模式空间并把下一行读入模式空间,进行相关处理;直到最后一行。sass

sed是无破坏性的,它不更改原文件,除非你使用重定向保存输出结果。bash

对于一行文本,sed命令是依次执行的,若是有多个命令的话。这时,要注意各命令之间可能产生的相互影响。编辑器

对于多个sed命令,咱们能够用“{}”把它们括起来。但要注意,右花括号必定要单独成行。测试

sed命令后不能有空格,前面则无所谓。this

咱们能够把一系列的sed命令写入文件中并用sed 的-f选项调用spa

好啦,打住先(没提到的后面都会有例子说明的,嘿嘿).net


首先,咱们来看看sed的语法及寻址方式:

语法:

sed [options] 'command' filename(s)

寻址方式:

1.单行寻址:[line-addresscommand;寻找匹配line-address的行并进行处理。

2.行集合寻址:[regexpcommand ;匹配文件中的一行或多行,如/^A/command匹配全部以A开头的行。

3.多行寻址: [line-address1line-address2] command;寻找在两个地址之间的内容并作相应的处理。

4.嵌套寻址:10,20

/^$/d

#上面三种寻址方法均可以应用在这里

接下来,瞧瞧sed的一些命令和选项

sed选项:

选项

功能

-e

容许屡次编辑

-f

跟随脚本文件名

-n

禁止默认输出


sed的相关命令:

命令

功能

a\

向当前行添加文本行

c\

用新的文本行取代当前行里的文本

i\

在当前行以前插入文本

d

删除行

h

把模式空间内容复制到一个固定缓存

H

把模式空间内容添加到一个固定缓存

g

把固定缓存里的全部文本都复制到模式缓存,重写模式缓存的内容

G

把固定缓存里的全部文本添加到模式缓存

l

列出不打印的字符

p

打印行

P(大写)

多行打印,输出多行模式空间里的第一部分,直到第一个嵌入的换行符为止

n

输出模式空间的内容并读取下一行

N

读取新的输入行并将其添加到模式空间的现有内容以后来建立多行模式空间

q

结束或退出

r

读入行,从某个文件

!

把命令应用到选定行以外的其它全部行

s

替换



替换标志:

标志

功能

g

全局替换

p

打印

w

把行写到文件中

x

交换;用模式空间的内容交换固定缓存的内容

y

转换,如大小写转换



sed支持的一些元字符:

元字符

功能

^

定位行开头

/^sed/:匹配全部以sed开头的行

$

定位行结尾

/sed$/:匹配全部以sed结尾的行

.

匹配单个字符,不包括换行符

/s.d/:匹配包含一个s,后跟一个字符,再跟一个e的行

*

匹配零个或多个字符

/*sed/:匹配的行有零个或多个空格且其后跟模式sed

[]

匹配集中的一个字符

/[Ss]ed/:匹配包含sedSed的行

[^]

反上

/[^Ss]ed/:匹配的行不包含sS且后跟ed

\(..\)

保存被匹配的字符

s/\(love\)/\1 ly/:用lovely取代love。把被标志的部分标为1,之后就能用\1引用。最多容许使用9个标记,第一个从模式的最左端开始。如上面的love就保存在寄存器1里且被记在替换串里。

&

保存搜索串以便记在替换串里

s/sed/fuck&/:&表明搜索串sed。此例中sed将被fucksed替换

\<

定位词开头

/\<sed/:匹配以sed开头的一个词

\>

定位词结尾

/sed\>/:匹配以sed结尾的一个词

x\{m\}

字符x重复m

o\{3\}:匹配的行里o要连续出现3

x\{m,\}

字符x至少重复m

o\{3\}:匹配的行里o至少要连续出现3

x\{m,n\}

字符x至少重复m次且不超过n

O\{3,5\}:匹配的行里要o至少要连续出现3次但不超过5


好啦,下面就有例子来讲话喔,呵呵

datafile的内容:

northwest NW Charles Main 3.0 .98 3 34 

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18 

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13 

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13 

e.g. 1:

a\--找到以north开头的行并在其后添加不少FUCK

[fedora@novice chap04]$ sed '/^north/a\FUCK FUCK FUCK FUCK \nkcuf kcuf kcuf kcuf' datafile 

northwest NW Charles Main 3.0 .98 3 34

FUCK FUCK FUCK FUCK 

kcuf kcuf kcuf kcuf 

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

FUCK FUCK FUCK FUCK 

kcuf kcuf kcuf kcuf 

north NO Margot Weber 4.5 .89 5 9 

FUCK FUCK FUCK FUCK 

kcuf kcuf kcuf kcuf 

central CT Ann Stephens 5.7 .94 5 13

***************************************************************************************************

发如今bash中只能像上面那样输入且a后的\无关紧要 ; 并不像书上说的那样,不知是否是跟SHELL有关系

通常,a后是要带\的,有时还要带两个。若是要添加的文本不止一行的话,除了最后一行每一行的结尾都要跟\。以上只是在控制台输入,在脚本中输入的状况仍是和书上说的同样的。

***************************************************************************************************


e.g. 2:

i\ --在以central开头的行前分行插入FUCK

[fedora@novice chap04]$ sed '/central/i\F\nU\nC\nK' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

***************************************************************************************************

通常,若是要添加的文本不止一行的话,除了最后一行每一行的结尾都要跟\。但在我这里好像有点不同,在终端直接输入时

****************************************************************************************************

e.g. 3:

c\--把有sourth的行所有用FUCK取代

[fedora@novice chap04]$ sed '/south/c\FUCK' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

FUCK 

FUCK

FUCK 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

****************************************************************************************************

*其它与e.g.1 ,e.g. 2 相似

****************************************************************************************************



e.g. 4:

d--删除第一行

[fedora@novice chap04]$ sed '1d' datafile 

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

d--删除14

[fedora@novice chap04]$ sed '1,4d' datafile 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

d--删除有north的行

[fedora@novice chap04]$ sed '/north/d' datafile 

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

central CT Ann Stephens 5.7 .94 5 13

***************************************************************************************************

e.g. 5:

s--替换。用FUCK替换north.

[fedora@novice chap04]$ sed 's/north/FUCK/' datafile 

FUCKwest NW Charles Main 3.0 .98 3 34 

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

FUCKeast NE AM Main Jr. 5.1 .94 3 13 

FUCK NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

s--替换。用FUCK替换全部以south开头的行中的south.

[fedora@novice chap04]$ sed '/^south/s/south/FUCK/g' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

FUCKwest SW Lewis Dalsass 2.7 .8 2 18 

FUCKern SO Suan Chin 5.1 .95 4 15 

FUCKeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

s--替换。 寻找大于1少于10的一位小数并用FUCK+&替代。这里的&保存了前面的小数

[fedora@novice chap04]$ sed 's/[0-9]\.[0-9]/FUCK&/' datafile 

northwest NW Charles Main FUCK3.0 .98 3 34 

western WE Sharon Gray FUCK5.3 .97 5 23 

southwest SW Lewis Dalsass FUCK2.7 .8 2 18 

southern SO Suan Chin FUCK5.1 .95 4 15

southeast SE Patricia Hemenway FUCK4.0 .7 4 17 

eastern EA TB Savage FUCK4.4 .84 5 20

northeast NE AM Main Jr. FUCK5.1 .94 3 13 

north NO Margot Weber FUCK4.5 .89 5 9 

central CT Ann Stephens FUCK5.7 .94 5 13 

****************************************************************************************************

刚开始时用的是下面的语句:

sed '[0-9][0-9]$/FUCK&/' datafile,怎么弄都不成功。

不知是怎么回事。

*****************************************************************************************************

e.g. 6:

p--打印:默认打印全部的行。这里用-n选项过滤无关的行

[fedora@novice chap04]$ sed -n '/north/p' datafile 

northwest NW Charles Main 3.0 .98 3 34

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

发现一个问题:p也会把匹配的行打印两次:

[fedora@novice chap04]$ sed '/north/p' datafile 

northwest NW Charles Main 3.0 .98 3 34

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94

也就是说不使用-n选项的话,p会打印出匹配两次

P--多行打印:在执行完全部命令后模式空间的内容会自动输出,在下面的例子中能够看到匹配的行输出了两次,可是-n选项会抑制这个动做。只有在与DN配合使用时才会输出模式空间里的第一行,此时不用-n选项。

[fedora@novice chap04]$ sed '/north/P' datafile 

northwest NW Charles Main 3.0 .98 3 34

northwest NW Charles Main 3.0 .98 3 34 

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

northeast NE AM Main Jr. 5.1 .94 3 13 

north NO Margot Weber 4.5 .89 5 9 

north NO Margot Weber 4.5 .89 5 9

central CT Ann Stephens 5.7 .94 5 13

****************************************************************************************************


e.g. 7:

D--多行删除:选项看到dD的不一样之处了么?其中空行分别为1234行。

[fedora@novice chap04]$ cat >test 

this is a test line 


this is a test line 



this is a test line 




this is a test line 





this ia a test line 

[fedora@novice chap04]$ sed -e '/^$/N' -e '/^\n$/d' test 

this is a test line 


this is a test line 

this is a test line 


this is a test line 

this ia a test line 

[fedora@novice chap04]$ sed -e '/^$/N' -e '/^\n$/D' test 

this is a test line 


this is a test line 


this is a test line 


this is a test line 


this ia a test line 

****************************************************************************************************

能够看到,与N配合的状况下:

使用d,如有偶数个空行将会全被删除,如有奇数个空行将会保留一行。这是由于d删除的是整个模式空间的内容。一旦遇到第一个空行就立刻读入下一行,而后两行都删除。若是第三行为空且下一行不为空则命令不执行,空行被输出。

使用D,当遇到两个空行时D会删除两个空行中的第一个,而后再读入下一行,若是是空行则删除第一行,若是空行后有文本则模式空间能够正常输出。

***************************************************************************************************

e.g. 8:关于N命令与-e选项在上面已在应用,这里就不举例啦,偷点懒哈,嘿嘿。

*****************************************************************************************************


e.g. 9:

r--从文件中读取:从test中读取相关的内容添加到datafile中全部匹配的行的后面。

[fedora@novice chap04]$ sed '/^south/r test' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

********************************** 

FUCK FUCK FUCK FUCK ,FUCK TOO MUCH 

********************************** 

southern SO Suan Chin 5.1 .95 4 15 

********************************** 

FUCK FUCK FUCK FUCK ,FUCK TOO MUCH 

********************************** 

southeast SE Patricia Hemenway 4.0 .7 4 17 

********************************** 

FUCK FUCK FUCK FUCK ,FUCK TOO MUCH 

********************************** 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

***************************************************************************************************

e.g. 10

w--写入文件:把datafile中全部匹配的行写入到test文件中

[fedora@novice chap04]$ sed '/^south/w test' datafile|cat test 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

***************************************************************************************************


e.g. 11

n--next:若是有能匹配western行,则n命令使得sed读取下一行,而后执行相应命令

[fedora@novice chap04]$ sed -e '/western/n' -e 's/SW/FUCK/' datafile|head -n 4 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest FUCK Lewis Dalsass 2.7 .8 2 18 

southern SO Suan Chin 5.1 .95 4 15 

***************************************************************************************************8


e.g. 12

y--变换:

[fedora@novice chap04]$ sed '3,5y/s/S/' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

SouthweSt SW LewiS DalSaSS 2.7 .8 2 18 

Southern SO Suan Chin 5.1 .95 4 15

SoutheaSt SE Patricia Hemenway 4.0 .7 4 17

eastern EA TB Savage 4.4 .84 5 20 


[fedora@novice chap04]$ sed '1y/3/9/' datafile 

northwest NW Charles Main 9.0 .98 9 94

western WE Sharon Gray 5.3 .97 5 23 

***************************************************************************************************

替换的类型要一致,数字与字母之间不能相互替换。

且对正则表达式的元字符不起做用。

*****************************************************************************************************


e.g. 13:

q--退出:

打印三行后退出

[fedora@novice chap04]$ sed '3q' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

用相应的字符作出替换后退出

[fedora@novice chap04]$ sed -e 'y/northwest/ABCDEFGHI/' -e q datafile 

ABCDEFGHD NW CEaClGH MaiA 3.0 .98 3 34

这样也能够的

[fedora@novice chap04]$ sed '{ y/northwest/ABCDEFGHI/; q;}' datafile 

ABCDEFGHD NW CEaClGH MaiA 3.0 .98 3 34

多个命令写在一行时能够用-e选项,也能够用花括号把全部命令括起来并用分号隔开且最后一个分号无关紧要,在个人实验环境下。

**************************************************************************************************

e.g. 14:

H/h/G/g--保存和取得

下面是这几个命令的一些组合,能看出些什么来么?

[fedora@novice chap04]$ sed -e '/northeast/h' -e '$g' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

northeast NE AM Main Jr. 5.1 .94 3 13

[fedora@novice chap04]$ sed -e '/northeast/h' -e '$G' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

northeast NE AM Main Jr. 5.1 .94 3 13

[fedora@novice chap04]$ sed -e '/northeast/H' -e '$g' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 


northeast NE AM Main Jr. 5.1 .94 3 13

[fedora@novice chap04]$ sed -e '/northeast/H' -e '$G' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13


northeast NE AM Main Jr. 5.1 .94 3 13


由于呢,H/G在相应空间的内容以后放置一个换行符,且后面紧跟模式空间的内容;而g/h的呢都是取代相应空间的内容,因此就有上面的不一样结果喔

***************************************************************************************************


e.g. 15

x--交换模式/保持空间内容

首先匹配第一个包含north的行放入保持缓存,而后匹配第一个包含south的行放入模式空间,最后把二者的内容交换。

[fedora@novice chap04]$ sed -e '/north/h' -e '/south/x' datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

northwest NW Charles Main 3.0 .98 3 34 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13


****************************************************************************************************


e.g. 16

sed脚本:

[fedora@novice chap04]$ vim sedlist 

/central/a\ 

------This is a test-------- 

/northeast/i\ 

------This is a test too------ 

[fedora@novice chap04]$ sed -f sedlist datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

------This is a test too------ 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

------This is a test-------- 

能够在里面添加注释,以#开头的行被认为是注释

若有多行,则每行都要以\结尾,除了最后一行。如,下面的脚本是能够正常执行的。

[fedora@novice chap04]$ cat sedlist 

#This script is a test for sed commands list 


/central/a\ 

------This is a test too--------\ 

------Hi am here----------------\ 


#now ,the second test 

/northeast/i\ 

------This is a test ------ 

***************************************************************************************************



****************************************************************************************************

*******************************************************************************************************

高级流控制命令

b  分支 :无条件转移

t  测试 :有条件的转移

它们将脚本中的控制转移到包含特殊标签的行;若是没有标签则直接转移到脚本的末尾。只有当替换命令改变当前行时才会被执行。


标签:任意的字符组合且长度不大于7,它自己占据一行且以冒号开头

mylabel

冒号和标签之间不能有空格,标签后的空格会被当作标签的一部分。

标签和命令之间容许有空格。



b  分支:[address] b [label]

b --> branch,在脚本中将控制权转到另外一行,经过它你能够跳到你想去的地方,是否是有点像c中的goto呀?

它能够将一组命令当作一个过程来执行且这个过程在脚本中能够重复执行,只要条件知足。

e.g 17

b--分支


看下面的例子:

e.g. 17.1

匹配以north加空格开头的行,若匹配则转到:label后面的命令,在以s开头的行前插入FFFFFFFFFFFFFFUCK 

[fedora@novice chap04]$ cat sedlist 

#This script is a test for sed commands

:label 

/^s/i\ 

FFFFFFFFFFFFFFUCK 

/^north / b label

[fedora@novice chap04]$ sed -f sedlist datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

FFFFFFFFFFFFFFUCK 

southwest SW Lewis Dalsass 2.7 .8 2 18

FFFFFFFFFFFFFFUCK 

southern SO Suan Chin 5.1 .95 4 15 

FFFFFFFFFFFFFFUCK 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

其实这也是个循环,反复执行两个标签间的命令,直到模式不匹配。可是,如上,无论匹配与否两个标签间的内容至少会被执行一次。也就是说,正常状况下上面的命令都会被执行一次。看下面的例子:

e.g 17.2

[fedora@novice chap04]$ cat sedlist 

#This script is a test for sed commands

:label 

/^n/d 

/^A/b label 

/^cent/a\ 

--FUCK!!! \ 

Just a test! \ 

Take it easy!!! 

[fedora@novice chap04]$ sed -f sedlist datafile 

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

central CT Ann Stephens 5.7 .94 5 13

--FUCK!!! 

Just a test! 

Take it easy!!! 

看到了吧!虽然模式不匹配,但仍是执行了两个标签间的内容,嘿嘿!再看看上面,和do-while语句有什么异同?

e.g. 17.3

若是匹配,什么都不作,不然执行后的命令向以cent开头的行后添加一些内容

[fedora@novice chap04]$ cat sedlist 

#This script is a test for sed commands

:label 

/^A/b label 

/^cent/a\ 

--FUCK!!! \ 

Just a test! \ 

Take it easy!!! 

[fedora@novice chap04]$ sed -f sedlist datafile 

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

--FUCK!!! 

Just a test! 

Take it easy!!!

e.g. 17.4

另外一种循环模式

command1

/pattern/b label

command2

label:

command3

首先执行command1,而后看模式是否匹配,若匹配则执行command3,不然执行command2command3

[fedora@novice chap04]$ cat sedlist 

#This script is a test for sed commands

/^n/d 

/^A/b label 

s/south/SSSSSS/ 

:label 

/^cent/a\ 

--FUCK!!! \ 

Just a test! \ 

Take it easy!!! 

[fedora@novice chap04]$ sed -f sedlist datafile 

western WE Sharon Gray 5.3 .97 5 23 

SSSSSSwest SW Lewis Dalsass 2.7 .8 2 18 

SSSSSSern SO Suan Chin 5.1 .95 4 15 

SSSSSSeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

central CT Ann Stephens 5.7 .94 5 13

--FUCK!!! 

Just a test! 

Take it easy!!! 

模式不匹配,顺序执行各命令,下面来看匹配的状况:

[fedora@novice chap04]$ cat sedlist 

#This script is a test for sed commands

/^w/d 

#north后有一个空格

/^north /b label 

s/south/SSSSSS/ 

:label 

/^cent/a\ 

--FUCK!!! \ 

Just a test! \ 

Take it easy!!! 

[fedora@novice chap04]$ sed -f sedlist datafile 

northwest NW Charles Main 3.0 .98 3 34

SSSSSSwest SW Lewis Dalsass 2.7 .8 2 18 

SSSSSSern SO Suan Chin 5.1 .95 4 15 

SSSSSSeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

--FUCK!!! 

Just a test! 

Take it easy!!! 

很显然,这里并无跳过第二个命令,可是理论上只模式空间匹配的话就会直接转到:label后的命令的呀!这究竟是为何呢?咱们来看下一个脚本,只对上个脚本作一点点修改:

[fedora@novice chap04]$ cat sedlist 

#This script is a test for sed commands

/^w/d 

#north后有一个空格

/^north /b label 

s/north /SSSSSS/ 

:label 

/^cent/a\ 

--FUCK!!! \ 

Just a test! \ 

Take it easy!!! 

[fedora@novice chap04]$ sed -f sedlist datafile 

northwest NW Charles Main 3.0 .98 3 34

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

--FUCK!!! 

Just a test! 

Take it easy!!! 

此次结果正常啦,它找到了以north加空格开头的行,并跳过了第二个命令。

再来看两个例子:

在第二个命令后再添加一个命令s/south/NNNNNN看会有怎样的结果:

[fedora@novice chap04]$ cat sedlist 

#This script is a test for sed commands

/^w/d 

/^north /b label 

s/north /SSSSSS/ 

s/south/NNNNNN/ 

:label 

/^cent/a\ 

--FUCK!!! \ 

Just a test! \ 

Take it easy!!! 

[fedora@novice chap04]$ sed -f sedlist datafile 

northwest NW Charles Main 3.0 .98 3 34

NNNNNNwest SW Lewis Dalsass 2.7 .8 2 18 

NNNNNNern SO Suan Chin 5.1 .95 4 15 

NNNNNNeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

--FUCK!!! 

Just a test! 

Take it easy!!! 

显然,s/north /SSSSSS/ 没有被执行而s/south/NNNNNN/ 被执行啦

又一个例子:

[fedora@novice chap04]$ cat sedlist1 

#This script is a test for sed commands

/^w/d 

/^north/b label 

:label 

/^cent/a\ 

--FUCK!!! \ 

Just a test! \ 

Take it easy!!! 

[fedora@novice chap04]$ sed -f sedlist1 datafile 

northwest NW Charles Main 3.0 .98 3 34

southwest SW Lewis Dalsass 2.7 .8 2 18

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

central CT Ann Stephens 5.7 .94 5 13

--FUCK!!! 

Just a test! 

Take it easy!!! 

能够看到p应用到了除以north开头的全部行!再来一个例子:

[fedora@novice chap04]$ cat sedlist1 

#This script is a test for sed commands

/^w/d 

/^north/b label 

:label 

/^cent/a\ 

--FUCK!!! \ 

Just a test! \ 

Take it easy!!! 

[fedora@novice chap04]$ sed -f sedlist1 datafile 

northwest NW Charles Main 3.0 .98 3 34

southwest SW Lewis Dalsass 2.7 .8 2 18

southwest\tSW\tLewis Dalsass\t\t2.7\t.8\t2\t18\r$ 

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15 

southern\tSO\tSuan Chin\t\t5.1\t.95\t4\t15\r$ 

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

southeast \tSE\tPatricia Hemenway\t4.0\t.7\t4\t17\r$ 

southeast SE Patricia Hemenway 4.0 .7 4 17 

eastern EA TB Savage 4.4 .84 5 20 

eastern\t\tEA\tTB Savage\t\t4.4\t.84\t5\t20\r$ 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

central\t\tCT \tAnn Stephens\t\t5.7\t.94\t5\t13\r$ 

central CT Ann Stephens 5.7 .94 5 13

--FUCK!!! 

Just a test! 

Take it easy!!! 

看到了么?P,l都只应用到了除以north开头的全部行上!!!

从上面的一堆例子中,能够获得:在

command1

/pattern/b label

command2

label:

command3

模式中 只有 针对 匹配pattern的行 的操做才会被跳过!

e.g. 17.5

如何指定执行上例中的command2command3中的一个

commmand1

/pattern/b label

command2

b

:label

command3

首先执行command1,而后执行/pattern/b label,若是模式匹配则直接跳到command3并执行相关命令,不然跳到command2在执行完相关命令后遇到分支b,分支b将控制转到脚本的结尾,绕过了command3.

下面看一个简单的例子:

[fedora@novice chap04]$ cat sedlist1 

#This script is a test for sed commands

/^e/d 

/^DDD/b label 

s/west/SSSSSS/ 

:label 

/^cent/a\ 

--FUCK!!! \ 

Just a test! \ 

Take it easy!!! 

[fedora@novice chap04]$ sed -f sedlist1 datafile 

northSSSSSS NW Charles Main 3.0 .98 3 34 

SSSSSSern WE Sharon Gray 5.3 .97 5 23

southSSSSSS SW Lewis Dalsass 2.7 .8 2 18 

southern SO Suan Chin 5.1 .95 4 15 

southeast SE Patricia Hemenway 4.0 .7 4 17 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

是吧,果真当模式不匹配时只执行command2:label后的命令没有被执行,哈哈

e.g. 18

t: [address] t [label]

t-->test,若是在当前匹配的行上成功地进行了替换,那么t命令就转到标签处或脚本末尾(未给定标签默认指向脚本末尾)。

t要单独成行


下面来一个简单的例子:

[fedora@novice chap04]$ cat sedlist 

/^s/d 

/^west/s/west/QQQ/ 

t label1 

/^n/y/nort/FUCK/ 

t label 

:label 

/^F/y/FUCK/nort/ 

:label1 

/^QQQ/s/QQQ/west/ 

[fedora@novice chap04]$ sed -f sedlist datafile 

northwest NW rharles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13


[fedora@novice chap04]$ cat sedlist 

/^s/d 

/^west/y/Q/a/ 

t label1 

/^n/y/nort/FUCK/ 

t label 

:label 

/^F/y/FUCK/nort/ 

:label1 

/^n/y/FUCK/nort/ 

[fedora@novice chap04]$ sed -f sedlist datafile 

northwest NW rharles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23 

eastern EA TB Savage 4.4 .84 5 20 

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9 

central CT Ann Stephens 5.7 .94 5 13

看出二者的区别了么?我相会的,嘿嘿

相关文章
相关标签/搜索