Commands which accept address ranges
{ Begin a block of commands (end with a }).
接受地址范围的命令
b label
Branch to label; if label is omitted, branch to end of script.
将控制分支到标签,如果标签被忽略,将控制分支到脚本后面。
解释:b指令是针对脚本的控制流来说的,意思就是它是用来转移控制,将当前的数据行传到b指令指定的标签后面,标签后的脚本继续处理该数据行。如果b没有指定具体的标签,即只有一个b,那么控制转移到脚本末尾,如果有具体而且存在的标签,将会将控制转移到指定标签后,这个叫无条件转移(就是不管怎么样,只要控制流到它这里,它都会转移,要么转移到具体标签后面,要么转移到脚本末尾)。
/ +++++++++++++++++++++++++++++++++++++++例子17+++++++++++++++++++++++++++++++++++++
请看“: label”那里。
/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
t label
If a s/// has done a successful substitution since the last input line was read and since the last t or T command, then branch to label;
if label is omitted, branch to end of script.
如果s指令发生替换操作,尽管已经读入输入的最后一行,或者已经是最后的t、T,都会转移到指定的标签后;如果忽略具体的标签,将会将控制转移到脚本末尾。
/ +++++++++++++++++++++++++++++++++++++++例子18+++++++++++++++++++++++++++++++++++++
sed.txt的内容为:
I feel so "cold" and the winter this year is "pretty
cold". I decide to buy some "winter clothes".
想把双引号换成<b>和</b>,即将"cold" 替换为:<b>cold</b>,由于这个的脚本复杂点,这次把放指令在sed.script文件里,sed.script中的指令内容为:
:begin
//(/"/)/([^/"]*/)/(/"/)/{ #匹配双引号和引号之间的内容,同时将正则表达式分三组
s//<b>/2<//b>/g #这里是替换指令,//表示上个正则表达式 /2表示前面正则表达式的第二部分
b begin #控制被转移到标签gebin后
}
/".*/{ #匹配只有一个双引号的行,例如 "pretty
N #构建多行模式空间,将下一行附加到当前行,并用换行符分隔
s//("/)/([^"]*/n[^"]*/)/("/)/<b>/2<//b>/g #匹配多行模式下的双引号和引号之间的内容
t again #如果上面的s指令成功替换,那么测试命令t将控制转移到again后
b begin #如果上面的s指令没有替换成功,那么分支命令b将控制转移到begin后
}
:again
P #大写的之母P,输出当前模式空间中的第一行
D #删除当前模式空间中的第一行,但是将控制转移到脚本开始来处理剩下的行
sed命令:sed –n –f sed.script sed.txt 整个命令执行流程如下:
sed将sed.txt第一行即:I feel so "cold" and the winter this year is "pretty
读入模式空间, 然后正则表达式 //(/"/)/([^/"]*/)/(/"/)/ 检查这一行,发现匹配了 "cold" 然后
进入第一个指令块,指令s//<b>/2<//b>/g将 "cold" 替换为<b>cold<//b> 其中 /2 代表cold,控制到达b begin ,b将控制转移到标签begin后;此时当前数据行的内容为:I feel so <b>cold</b> and the winter this year is "pretty 然后正则表达式 //(/"/)/([^/"]*/)/(/"/)/ 检查这一行,发现不匹配了;控制跳过第一个指令块,到达 /".*/ 即第二个指令块的开始,正则表达式/".*/ 检查这一行,发现匹配了当前行的 "pretty ,进入这个指令块,N命令将当前行的下一行读取进模式空间追加到当前行后面,并用换行符分隔,此时模式空间中的内容为:I feel so <b>cold</b> and the winter this year is "pretty/n cold". I decide to buy some "winter clothes",然后指令
s中的正则表达式//("/)/([^"]*/n[^"]*/)/("/)/去检查当前模式空间的内容,发现匹配了"pretty/n
cold",s命令就将"pretty/n cold"替换为<b>pretty/n cold</b>,控制到了t again处,测试命令t被告知s命令发生替换了,这个时候t指令将控制流转移到标签again后,执行P(大写的),这个指令会将I feel so <b>cold</b> and the winter this year is <b>pretty/n cold</b>. I decide to buy some "winter clothes"中换行符/n 之前的内容(包括换行符)即:I feel so <b>cold</b> and the winter this year is <b>pretty/n 打印出来,这个时候遇到D命令,这个命令和d不一样,D只会将模式空间中直到第一个嵌入的换行符的这部分内容,这个时候当前行的内容变为: cold</b>. I decide to buy some "winter clothes",然后它不会导致读入新的输入新行,在将当前控制转移到脚
本开始,即将当前行又从头开始执行指令,继续看它的流程……
第一个正则表达式 //(/"/)/([^/"]*/)/(/"/)/ 检查数据行cold</b>. I decide to buy some "winter clothes" 发现匹配了"winter clothes"好了,进入第一个指令块,s指令将"winter clothes"替换为<b>winter clothes</b>,然后制到达b begin ,b将控制转移到标签begin后,当前内容为:
cold</b>. I decide to buy some <b>winter clothes</b>;正则表达式 //(/"/)/([^/"]*/)/(/"/)/ 检查该行,但是不匹配了,控制跳到/".*/ 它检查数据行,发现不匹配了,控制跳过该数据块,到达P,这个时候只有一行数据了,P直接把它打印,到了D,由于模式空间只有一行数据,删除这行数据,模式空间没有内容,也没有输入流了,整个流程完成,最后显示的结果是:
I feel so <b>cold</b> and the winter this year is <b>pretty
cold</b>. I decide to buy some <b>winter clothes</b>.
/+++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++
T label
If no s/// has done a successful substitution since the last input line was read and since the last t or T command, then branch to label;
if label is omitted, branch to end of script.
和t差不多,只是这里是s指令没有发生替换操作然后就转移控制到指定标签,如果s指令发生替换,就不转移控制。
/ +++++++++++++++++++++++++++++++++++++++例子19+++++++++++++++++++++++++++++++++++++
sed.txt的内容为:
Redhat and Ubuntu are both great operating systems.
redhat and Ubuntu are both great operating systems.
sed脚本放在sed.script文件中,脚本内容如下:
s/Redhat/REDHAT/g #将Redhat替换为REDHAT
T another #如果上面没有发生替换,则将控制转移到another标签后
b end #如果控制流到达这里都无条件的转移到end标签
:another
s/Ubuntu/UBUNTU/g
:end
p #打印当前模式空间的内容
意思就是说如果将Redhat替换替换成了REDHAT 就不用替换同行的Ubuntu,如果没有将Redhat替换替换成了REDHAT,替换同行的Ubuntu为UBUNTU ;所以执行sed命令:sed -n -f sed.script sed.txt后结果如下:
REDHAT and Ubuntu are both great operating systems.
redhat and UBUNTU are both great operating systems.
/+++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++
c /
text Replace the selected lines with text, which has each embedded newline preceded by a backslash.
用新的文本去修改选定的行,新的文本行用反斜杠“/”与c命令隔开。
补充: c命令将选定的行修改为新的文本,如果指定的是一个地址范围,c指令将把整个范围内的行替换成新文本。
/ +++++++++++++++++++++++++++++++++++++++例子20+++++++++++++++++++++++++++++++++++++
sed.txt的内容为:
This is a dog.
This is a cat.
This is a horse.
This is a lion.
sed命令为:
sed -ne '1,3c/ #按Enter换行
>This is a bird.
>p' sed.txt
运行后的结果为:
This is a bird.
This is a lion.
也就是说c/命令将1-3的一共三行替换为This is a bird.
如果将c/命令换成i/命令即:
sed -ne '1,3i/ #按Enter换行
>This is a bird.
>p' sed.txt
执行以后结果为:
This is a bird.
This is a dog.
This is a bird.
This is a cat.
This is a bird.
This is a horse.
This is a lion.
可以看到在1-3一共三行,每行的前面插入This is a bird.这一行,它与c/命令不同就在于此。
/+++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++