匹配模式追加行但排除模式行

时间:2013-12-11 17:02:06

标签: sed awk

我想添加

 <br \> 

在标记

之间的每一行的末尾
 <div> ... </div>

源文件

 bla bala
 <div>
 bla bala
 bla bala
 bla bala
 </div>
 bla bala

我希望像

一样
 bla bala
 <div>
 bla bala <br \>
 bla bala <br \>
 bla bala <br \>
 </div>
 bla bala

我尝试了这个,但它也添加到标记行

 sed -i '' '/<pre\>/,/<\/pre\>/ s/$/<br \\>/' test.txt

也试过这个

 sed -i '' '/<pre\>/,/<\/pre\>/{/$/<br \\>/;}' test.txt

如何排除具有匹配模式的行?

更新:你能用sed吗?

3 个答案:

答案 0 :(得分:4)

这样的事情就是这样:

$ awk '/<\/div>/ {p=0} p{$0=$0"<br \>"} /<div>/ {p=1} 1' file
bla bala
<div>
bla bala<br \>
bla bala<br \>
bla bala<br \>
</div>
bla bala

答案 1 :(得分:2)

使用sed

sed '/<div>/,/<\/div>/s/[^>]$/<br \/>/' test.html

它将替换命令应用于由,分隔的开始和结束模式描述的一系列行:

/<div>/,/<\/div>/

替代命令(简化):

s/$/<br \/>/

...将使用<br />标记替换行结尾。

不幸的是,模式范围包括开始和结束<div>标记,并且没有办法告诉sed它应该只使用开始和结束模式之间的行。这就是为什么我添加了[^>]以避免将\n放在标记之后,这是最后的命令:

s/[^>]$/<br \/>/

将替换仅应用于<div>标记之间的行的另一种解决方案可能看起来像这样(可能更干净,更通用):

 sed '/<div>/,/<\/div>/ {/<div>/n; /<\/div>/ ! {s/$/<br \/>/}}' test.html

它将选择包括开始和结束div标签的范围以及它们之间的线,如上例所示,但是然后使用<div>命令和结束{{}跳过开始n标签。 1}}在花括号之间的下一个块之前使用</div>。有关详情,请查看this


然而,尽管我喜欢使用!玩得开心,但我不会使用正则表达式来操纵真实世界的应用程序中的html或xml文档。我会用xslt来做这件事。

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed '/<div>/,/<\/div>/!b;//!s/$/ <br \\>/' file

Sed有一个功能,即空的正则表达式采用之前的正则表达式值。