如何使用sed单趟处理匹配的两行注释并完成内容替换
问题解答
1. sed单趟实现可行性
完全可以通过sed的N;P;D循环单趟完成需求,不需要读取整个文件,处理效率足够高。
示例代码(假设你要把第二行< >里的内容替换为myvalue,可自行修改;GNU sed要直接修改原文件可加-i参数,macOS sed加-i ''):
sed '/^#foo:/{N;/\n#.*bar=/{s/^#//;s/\n#/\n/;s/<[^>]*>/myvalue/};P;D}' your_file
代码逻辑说明:
- 先匹配以
#foo:开头的行,匹配到后执行大括号内逻辑 - 用
N命令把下一行追加到当前模式空间 - 判断追加后的内容是否包含
\n#.*bar=,也就是第二行开头带#且包含bar=的情况 - 匹配成功后依次做三个替换:
- 去掉第一行开头的
# - 去掉第二行开头的
# - 把第二行中< >包裹的内容替换为目标值
- 去掉第一行开头的
- 最后执行
P;D打印模式空间第一行,删除第一行后进入下一轮循环,保证逐行扫描不会漏过相邻匹配的情况
2. 更简单的实现方式
如果不需要严格限制用sed,用awk实现可读性会更高,逻辑更清晰,不容易写错正则:
awk ' prev ~ /^#foo:/ && /^#.*bar=/{ sub(/^#/,"",prev) sub(/^#/,"") sub(/<[^>]*>/,"myvalue") print prev print prev="" next } {if(prev!="") print prev; prev=$0} END{if(prev!="") print prev} ' your_file
如果可以接受直接修改文件,也可以用perl的单行命令,处理多行匹配更灵活,没有嵌套匹配场景下是最短的写法:
perl -0777 -pi 's/#(foo:\n)#(\s*bar=)<[^>]*>/$1$2myvalue/g' your_file
内容的提问来源于stack exchange,提问作者JoyceLee
相关产品推荐
相关产品推荐

