使用反向引用在两个模式之间重写 SED 正则表达式
SED Regex rewriting between two patterns using backreferences
我在许多 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-->
我正在使用这个:
sed -E -i 's/(<!-- BEGIN FOOTER -->)(.|\n)*(<!--END FOOTER-->)/ <br>REPLACE<br> /m' file.html
但无法捕获和反向引用它们:
<!-- BEGIN FOOTER -->
<!--END FOOTER-->
并在它们之间插入:
REPLACE
所以尝试以这样的方式结束:
<!-- BEGIN FOOTER -->
<br>REPLACE<br>
<!--END FOOTER-->
这可能适合您 (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>'
sed
从输入文件中一次读取一行并将结果定向到标准输出。这意味着在输入行中没有要匹配的 \n
字符,除非在某些情况下使用了一些特殊命令。您可以使用地址范围和 insert i
命令来获得所需的输出:
sed '/BEGIN FOOTER/,/END FOOTER/{ /END FOOTER/{i\<br>REPLACE<br>
b}; /BEGIN FOOTER/b; d;}' file
注意第一行后的换行符。 i
在模式 space 中的当前行之前插入数据。 b
跳过剩余的命令,导致新的迭代完成。 /BEGIN FOOTER/,/END FOOTER/
表示其他命令应执行的范围。
您可以先将BEGIN FOOTER
和END FOOTER
行保存在beg
和end
变量中:
beg=$(grep -n "BEGIN FOOTER" inputfile | cut -d: -f1)
end=$(grep -n "END FOOTER" inputfile| cut -d: -f1)
然后使用sed的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
我在许多 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-->
我正在使用这个:
sed -E -i 's/(<!-- BEGIN FOOTER -->)(.|\n)*(<!--END FOOTER-->)/ <br>REPLACE<br> /m' file.html
但无法捕获和反向引用它们:
<!-- BEGIN FOOTER -->
<!--END FOOTER-->
并在它们之间插入:
REPLACE
所以尝试以这样的方式结束:
<!-- BEGIN FOOTER -->
<br>REPLACE<br>
<!--END FOOTER-->
这可能适合您 (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>'
sed
从输入文件中一次读取一行并将结果定向到标准输出。这意味着在输入行中没有要匹配的 \n
字符,除非在某些情况下使用了一些特殊命令。您可以使用地址范围和 insert i
命令来获得所需的输出:
sed '/BEGIN FOOTER/,/END FOOTER/{ /END FOOTER/{i\<br>REPLACE<br>
b}; /BEGIN FOOTER/b; d;}' file
注意第一行后的换行符。 i
在模式 space 中的当前行之前插入数据。 b
跳过剩余的命令,导致新的迭代完成。 /BEGIN FOOTER/,/END FOOTER/
表示其他命令应执行的范围。
您可以先将BEGIN FOOTER
和END FOOTER
行保存在beg
和end
变量中:
beg=$(grep -n "BEGIN FOOTER" inputfile | cut -d: -f1)
end=$(grep -n "END FOOTER" inputfile| cut -d: -f1)
然后使用sed的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