追求卓越,成功就会在不经意间追上你
全部博文(112)
分类: Python/Ruby
2011-05-10 17:38:26
高级流控制命令
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,否则执行command2,command3
[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
p
: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
p
l
: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
如何指定执行上例中的command2或command3中的一个
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/
b
: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
看出两者的区别了么?我相会的,嘿嘿