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

原文地址:sed实例精解--例说sed完整版 作者:xiaozhenggang

最近在学习shell,怕学了后面忘了前面的就把学习和实验的过程记录下来了。这里是关于sed的,前面有三四篇分开的,现在都把它们弄到了一起,并做了一些调整,二十多页,有点长啦。不过大部分都是例子来着,呵呵。

在电脑前坐太久了还真是不行,脖子都歪啦!强烈建议各位找点时间多动动,多动动!还是身体重要嘛!!!

我的实验环境是: fedora 14 ,bash。

在实验中遇到了一些问题,都在后面的例子中提到啦。有些问题纠结了好久,才发现只是多了或少了一个空格的问题,汗......

这中间肯定还有很多问题,热烈欢迎各位赐教!

路才开始,努力,坚持,加油!!!

例说sed

sed:stream
editor

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

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

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

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

对于多个sed命令,我们可以用“{}”把它们括起来。但要注意,右花括号一定要单独成行。

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

我们可以把一系列的sed命令写入文件中并用sed
的-f选项调用

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

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

语法:

sed [options]
‘command‘ filename(s)

寻址方式:

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

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

3.多行寻址:
[line-address1,line-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/:匹配包含sed或Sed的行


[^]


反上


/[^Ss]ed/:匹配的行不包含s,S且后跟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

[[email protected] 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

[[email protected] 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

F

U

C

K

central CT Ann Stephens 5.7 .94 5 13

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

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

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

e.g. 3:

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

[[email protected] 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--删除第一行

[[email protected] 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--删除1-4行

[[email protected] 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的行

[[email protected] 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.

[[email protected] 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.

[[email protected] 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+&替代。这里的&保存了前面的小数

[[email protected] 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选项过滤无关的行

[[email protected] 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也会把匹配的行打印两次:

[[email protected] 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选项会抑制这个动作。只有在与D,N配合使用时才会输出模式空间里的第一行,此时不用-n选项。

[[email protected] 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--多行删除:选项看到d与D的不同之处了么?其中空行分别为1,2,3,4行。

[[email protected] 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

[[email protected] 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

[[email protected] 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中所有匹配的行的后面。

[[email protected] 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文件中

[[email protected] 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读取下一行,然后执行相应命令

[[email protected] 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--变换:

[[email protected] 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

[[email protected] 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--退出:

打印三行后退出

[[email protected] 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

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

[[email protected] chap04]$ sed -e
‘y/northwest/ABCDEFGHI/‘ -e q datafile

ABCDEFGHD NW CEaClGH MaiA 3.0 .98 3 34

这样也可以的

[[email protected] chap04]$ sed ‘{
y/northwest/ABCDEFGHI/; q;}‘ datafile

ABCDEFGHD NW CEaClGH MaiA 3.0 .98 3 34

多个命令写在一行时可以用-e选项,也可以用花括号把所有命令括起来并用分号隔开且最后一个分号可有可无,在我的实验环境下。

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

e.g. 14:

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

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

[[email protected] 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

[[email protected] 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

[[email protected] 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

[[email protected] 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的行放入模式空间,最后把两者的内容交换。

[[email protected] 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脚本:

[[email protected] chap04]$ vim sedlist

/central/a\

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

/northeast/i\

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

[[email protected] 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--------

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

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

[[email protected] 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

[[email protected] chap04]$ cat sedlist

#This script is a test for sed commands

:label

/^s/i\

FFFFFFFFFFFFFFUCK

/^north / b label

[[email protected] 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

[[email protected] 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!!!

[[email protected] 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开头的行后添加一些内容

[[email protected] chap04]$ cat sedlist

#This script is a test for sed commands

:label

/^A/b label

/^cent/a\

--FUCK!!! \

Just a test! \

Take it easy!!!

[[email protected] 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,否则执行command2,command3

[[email protected] 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!!!

[[email protected]
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!!!

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

[[email protected] 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!!!

[[email protected] 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后的命令的呀!这到底是为什么呢?我们来看下一个脚本,只对上个脚本做一点点修改:

[[email protected] 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!!!

[[email protected] 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看会有怎样的结果:

[[email protected] 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!!!

[[email protected] 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/
被执行啦

又一个例子:

[[email protected] chap04]$ cat sedlist1

#This script is a test for sed commands

/^w/d

/^north/b label

p

:label

/^cent/a\

--FUCK!!! \

Just a test! \

Take it easy!!!

[[email protected] 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开头的所有行!再来一个例子:

[[email protected] chap04]$ cat sedlist1

#This script is a test for sed commands

/^w/d

/^north/b label

p

l

:label

/^cent/a\

--FUCK!!! \

Just a test! \

Take it easy!!!

[[email protected] 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

如何指定执行上例中的command2或command3中的一个

commmand1

/pattern/b label

command2

b

:label

command3

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

下面看一个简单的例子:

[[email protected] chap04]$ cat sedlist1

#This script is a test for sed commands

/^e/d

/^DDD/b label

s/west/SSSSSS/

b

:label

/^cent/a\

--FUCK!!! \

Just a test! \

Take it easy!!!

[[email protected] 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要单独成行

下面来一个简单的例子:

[[email protected] 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/

[[email protected] 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

[[email protected] 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/

[[email protected] 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

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

时间: 2024-08-05 23:16:35

sed实例精解--例说sed完整版的相关文章

Linux 之 sed 实例详解

sed 实例详解 文本内容: 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO 1.sed 增加内容 -a 往文本或号后面增加内容 -i 往行号前增加内容 -a 实例:在Alex 前增加111,Kang,OOO [[email protected] ~]# sed '1a 111,Kang,OOO' test.txt 101,oldboy,CEO 111,Kang,OOO 102,zhangyao,CTO

Oracle PLSQL 实例精解 中文版pdf

下载地址:网盘下载 <Oracle PLSQL 实例精解>是一本逐步分解的,详尽的pl/sql编程教程,使用真实场景的试验.范例和练习来介绍读者所需的pl/sql编程技能,涵盖oracle 11g的最新特性.作者的写作手法源自于在哥伦比亚大学教授pl/sql编程技术的经验,深度探索pl/sql编程技术,融合自己的最佳实践.使用本书,读者可以快速掌握pl/sql编程基本知识,并建立工程化的概念,是市面上难得的pl/sql教程.下载地址:网盘下载

MATLAB神经网络原理与实例精解视频教程

教程内容:<MATLAB神经网络原理与实例精解>随书附带源程序.rar9.随机神经网络.rar8.反馈神经网络.rar7.自组织竞争神经网络.rar6.径向基函数网络.rar5.BP神经网络.rar4.线性神经网络.rar3.单层感知器.rar2.MATLAB函数与神经网络工具箱.rar11.神经网络应用实例.rar10.用GUI设计神经网络.rar1.神经网络概述与MATLAB快速入门.rar下载地址:http://www.fu83.cn/thread-323-1-1.html

ORACLE PL/SQL 实例精解之第二章 通用编程语言基础

通用编程语言基础 2.1PL/SQL编程基础 1. 字符类型:支持四中类型字符:字母,数字,符号和空格,组合一个或多个字符就会创建一个词汇单元 2. 词汇单元 a.标识符必须以字符开头 b.保留字是pl/sql专用词 c. 定界符只对pl/sql有特殊含义的字符(算数操作和引号) d.注解单行(--)多行(/**/) 2.1.1 利用语言组件 字符类和词汇单元相当于字母和拼写单词 2.1.2 利用PL/SQL变量 a v_a 和V_A是相同的变量名,PL/SQL不区分大小写 b. 可以使用coa

ORACLE PL/SQL 实例精解之第一章 PL/SQL概念

1.传统一层一层传数据,而PLSQL作为独立的单元返回客户端,减少查询,减少网路传输的往返,搞笑 2.PL/SQL语句块 分为两种:命名(子程序,函数,包保存在数据库中,后期可以根据名称进行引用),匿名 区别:命名语句块存储在数据库中,用名称来引用,而匿名的语句块没有名称,不会存数在数据库中,后期无法引用 PL/SQL语句块分为三部分:声明,可执行(可执行是必须存在的),异常 声明就是定义变量,常量,分号结束,即为标识符的定义,如常量和游标保留DECLARE 可执行就是有保留字BEGIN和end

ORACLE PL/SQL 实例精解之第四章 条件控制:if 语句

4.1 IF 语句 IF语句两种形式:IF-THEN IF-THEN-ELSE 使用IF-THEN,可以指定需要执行的一组动作. IF-THEN-ELSE语句指定两组动作 1. IF-THEN TRUE执行语句序列 结构: IF CONDITION THEN STATEMENT 1; ....... STATEMENT N; END IF; 2. IF - THEN- ELSE语句 IF-THEN指定当前条件计算为true时,需要执行语句序列.当条件计算为false时,不采取任何特别活动,仅仅是

ORACLE PL/SQL 实例精解之第三章 PL/SQL中的SQL

3.1 在PL/SQL中使用DML 在PL/SQL语块中,两种变量赋值a. := 初始化.b. select into语法,PL/SQL语块的声明部分被声明的变量,后期可以使用选择语句进行赋值. 3.1.1变量初始化时使用select into语法 select A INTO V_A INSERT INTO xxx(表)( XA)values (V_A) 3.1.2 在pl/sql语句块中使用DML a.使用oracle序列 CURR b.获取和递增序列值 CURRVAL 返回序列的当前值 NE

ORACLE PL/SQL 实例精解之第五章 条件控制:CASE语句

5.1 CASE语句 1. CASE语句具有如下结构 CASE SELECTOR WHEN EXPRESSION 1 THEN STATEMENT 1; WHEN EXPRESSSION 2 THEN STATEMENT 2; ........ WHEN EXPRESSION N THEN STATEMENT N; ELSE STATEMENT N+1; END CASE; 保留字CASE标识CASE语句的开始.选择器决定哪个WHEN子句应该被执行.每个WHEN子句都包含一个EXPRESSION

ORACLE PL/SQL 实例精解之第六章 迭代控制之一

6.1 简单循环 简单循环,就想其名称一张,是一种最基本循环.简单循环具有如下结构 LOOP STATEMENT 1; STATEMENT 2; ... STATEMENT N; END LOOP; 保留字LOOP标识简单循环的开始.STATEMENT1到STATEMENT N 是反复执行的语句序列.这些语句由一个或者多个标准的编程结构组成.END LOOP是标识循环结构结束的保留字 每次循环迭代处理时,一些列语句会执行,然后再次执行循环最开始的语句.上述语句序列会无限制的执行,因为没有语句指定