如何编写sed脚本 保留起止标记并替换标记间内容为外部文件内容
sed保留标记替换区间内容实现方案
原有命令问题
原命令的匹配区间/<!-- Start -->/,/<!-- End -->/会将起止标记本身纳入操作范围,执行d删除操作时会连同标记一起清除,无法满足保留标记的需求。
正确实现命令
直接读取外部snippet文件的稳定写法(兼容绝大多数GNU sed环境,推荐使用):
sed -i -e '/<!-- Start -->/{p;r snippet.html' -e ':a' -e 'n;/<!-- End -->/!ba' -e '}' index.html
命令逻辑说明
- 匹配到
<!-- Start -->起始标记行时:- 执行
p打印当前标记行,保证起始标记保留 - 执行
r snippet.html读取外部文件内容,插入到起始标记之后输出 - 定义循环标签
a,通过n逐行读取后续内容,只要没读到<!-- End -->结束标记就持续跳转循环,跳过所有中间旧内容不输出
- 执行
- 循环读到结束标记行时,自动退出循环,sed默认打印当前结束标记行,之后继续处理文件剩余内容
- 全程起止标记不会被删除,重复执行命令只会替换两个标记中间的内容,不会破坏文件结构
如果需要通过管道传递动态生成的替换内容(而非固定文件),可以使用以下适配写法(仅支持GNU sed):
cat snippet.html | sed -i -e '/<!-- Start -->/{p;r /dev/stdin' -e ':a' -e 'n;/<!-- End -->/!ba' -e '}' index.html
执行效果
替换完成后的index.html对应片段结构如下,起止标记完整保留,中间内容替换为目标内容:
... <!-- Start --> <p>New content</p> <!-- End --> ...
内容的提问来源于stack exchange,提问作者Jorge Barata
相关产品推荐
相关产品推荐

