使用awk或sed替换文件中两个指定模式之间的目标字符串
指定区间替换文本的命令实现
需求描述
现有文本文件内容如下:
Dummy lines #### topo ######## Image version is v1 path is url/v1 Use the image v1 for deploying ################## some more dummy lines
需要实现范围替换规则:仅在#### topo ########与##################两行划定的区间内,将所有v1替换为v2,区间外内容保持不变,预期输出结果为:
Dummy lines #### topo ######## Image version is v2 path is url/v2 Use the image v2 for deploying ################## some more dummy lines
可通过sed或awk命令实现,具体方案如下。
sed 方案
sed原生支持按匹配范围执行操作,命令非常简洁:
# 预览替换结果,不修改原文件 sed '/#### topo ########/,/##################/s/v1/v2/g' 目标文件路径
确认结果符合预期后,加-i参数直接修改原文件:
sed -i '/#### topo ########/,/##################/s/v1/v2/g' 目标文件路径
逻辑说明:
/起始匹配模式/,/结束匹配模式/是sed的范围寻址语法,覆盖从起始匹配行到结束匹配行的所有内容- 后续的
s/v1/v2/g代表对寻址范围内的行执行全局替换,范围外的行不会执行任何修改 - 本场景中两个边界行本身不包含
v1字符串,即使被纳入替换范围也不会产生额外改动。
awk 方案
通过标记位判断当前行是否处于目标区间,再决定是否执行替换:
# 预览替换结果 awk '/#### topo ########/{f=1} /##################/{f=0} f{gsub(/v1/,"v2")} 1' 目标文件路径
确认结果无误后,通过临时文件中转写回原文件(awk没有直接修改原文件的原生参数,不要直接用>重定向到原文件,会清空文件内容):
awk '/#### topo ########/{f=1} /##################/{f=0} f{gsub(/v1/,"v2")} 1' 目标文件路径 > tmp && mv tmp 目标文件路径
逻辑说明:
- 匹配到区间起始行时,将标记变量
f设为1(代表进入替换区间);匹配到区间结束行时,将f设为0(代表离开替换区间) - 当
f为真值(处于替换区间内)时,调用gsub函数全局替换当前行的v1为v2 - 末尾的
1是awk简写语法,等价于{print $0},即打印所有行的内容,不区分是否在区间内 - 标记位判断顺序保证结束行不会被执行替换,逻辑完全符合需求。
内容的提问来源于stack exchange,提问作者christbanerjee
相关产品推荐
相关产品推荐

