SED正则表达式使用反向引用在两种模式之间重写

时间:2018-04-18 07:10:29

标签: regex sed backreference

我在许多html文件中都有这种格式的文本:



<!-- BEGIN FOOTER -->
<div id="footer"> 
  <p align="right"> Slogan<br />
    5555 Street East <br />
    City, State 99999 <br />
    Call Us (555)555-5555 <br />
</p>
    
<div align="center">
<a class="footer" href="http://www.example.com" title="Site">Site</a>
</div>


 <br>

</div>
<!--END FOOTER-->
&#13;
&#13;
&#13;

我正在使用它:

sed -E -i 's/(<!-- BEGIN FOOTER -->)(.|\n)*(<!--END FOOTER-->)/\1 <br>REPLACE<br> \3 /m'  file.html

但没有努力捕获&amp;反思他们:

\1 <!-- BEGIN FOOTER --> 
\3 <!--END FOOTER--> 

将它插入它们之间:

REPLACE

所以试图结束这个:

&#13;
&#13;
<!-- BEGIN FOOTER -->
<br>REPLACE<br>
<!--END FOOTER-->
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:0)

这可能适合你(GNU sed):

sed '/<!-- BEGIN FOOTER -->/{:a;N;/<!--END FOOTER-->/!ba;s/\n.*\n/\n<br>REPLACE<br>\n/}' file

这会收集页脚之间的行,并用所需的字符串替换它们之间的行。

替代方案(类似于revo);

sed '/<!-- BEGIN FOOTER -->/,/<!--END FOOTER-->/!b;/<!-- BEGIN FOOTER -->/b;/<!--END FOOTER-->/!d;i\<br>REPLACE<br>' file

另一种方式:

sed '/<!-- BEGIN FOOTER -->/,/<!--END FOOTER-->/!b;/<!--END FOOTER-->/p | sed '/<!-- BEGIN FOOTER -->/p;/<!-- BEGIN FOOTER -->/,/<!--END FOOTER-->/c\<br>REPLACE<br>' 

答案 1 :(得分:0)

sed一次从输入文件中读取一行,并将结果指向标准输出。这意味着在输入行中没有匹配\n字符的位置,除非在某些情况下使用了一些特殊命令。您可以使用地址范围以及insert i命令来实现所需的输出:

sed '/BEGIN FOOTER/,/END FOOTER/{ /END FOOTER/{i\<br>REPLACE<br>
b}; /BEGIN FOOTER/b; d;}' file

在第一行后观看换行符。 i在模式空间中的当前行之前插入数据。 b跳过剩余的命令,导致新的迭代。 /BEGIN FOOTER/,/END FOOTER/表示其他命令应该执行的范围。

答案 2 :(得分:0)

您可以先在BEGIN FOOTEREND FOOTER个变量中保存begend行:

beg=$(grep -n "BEGIN FOOTER" inputfile | cut -d: -f1)
end=$(grep -n "END FOOTER" inputfile| cut -d: -f1)

然后使用sed&#39; c\命令:

sed -i.bak "$((beg+1)),$((end-1))c\<br>REPLACE<br>" inputfile

结果:

<!-- BEGIN FOOTER -->
<br>REPLACE<br>
<!--END FOOTER-->

或者使用单个命令:

sed "/BEGIN FOO/,/END FOO/c\<!--BEGIN FOOTER-->\n<br>REPLACE<br>\n<!--END FOOTER-->" inputfile