如何用sed匹配含变量的行后,替换其下一行的首个指定字符串
sed结合变量实现多行匹配替换的解决方案
核心问题原因
问题本质是shell引号规则和sed语法的冲突:
- 单引号包裹的内容中,shell不会展开任何变量,因此
'/search$n/'里的$n会被sed当做字面量匹配,无法命中目标内容 - 双引号包裹的内容中,shell会展开
$开头的变量/特殊标识,因此sed语法里的$!(代表除最后一行外执行后续操作)如果不转义,会被shell解析为后台最后运行进程的PID,导致sed指令错误
可直接运行的正确命令
首先定义变量:
n=2 # 替换值可自定义,也可根据n动态生成 replace_val="foo"
写法1:基于原N/P/D逻辑调整
sed "\$!N;/search$n/ s/string/$replace_val/;P;D" test
写法2:更简洁的匹配后跳行逻辑(推荐,可读性更高)
匹配到目标行后直接跳转到下一行执行替换,逻辑更清晰:
sed "/search$n/{n;s/string/$replace_val/}" test
OSX系统注意事项
如果调用的是系统自带的BSD sed,部分GNU sed语法不生效,你提到已经安装gnu-sed,只需要把上述命令中的sed替换为gsed即可(brew安装的gnu-sed默认命令为gsed)。
如果需要原地修改文件,添加-i参数即可;需要备份原文件的话可以写成-i.bak,会自动生成后缀为.bak的备份文件。
批量循环实现多序号替换
如果需要按序号批量替换,可以直接套shell循环:
# 示例:替换search1到search3对应的string为val1到val3 for n in {1..3}; do replace_val="val$n" gsed -i "/search$n/{n;s/string/$replace_val/}" test done
内容的提问来源于stack exchange,提问作者user12536291
相关产品推荐
相关产品推荐

