如何用Shell脚本替换文件指定区间字符串并支持变量传入?
解决方案:用sed/awk替换指定路径后的子串(支持变量传入)
我来帮你搞定这个文本替换需求,你之前的sed命令误用了地址范围语法,咱们需要的是替换行内特定子串,下面是两种靠谱的实现方式:
方法1:使用sed命令(推荐,更简洁)
固定替换值(直接用R03_0)
我们可以用sed的正则分组替换,精准匹配dir_1=/dir_2=后面固定路径到;之间的内容,替换成目标值:
sed -E 's/(dir_[12]=\/some\/other\/path\/to\/a\/directory\/)[^;]+;/\1R03_0;/g' info.txt
细节解释:
-E:启用扩展正则,让分组()不用额外转义,写起来更清爽(dir_[12]=\/some\/other\/path\/to\/a\/directory\/):捕获我们要保留的固定前缀(dir_1=/dir_2=加上指定路径),后面用\1引用这个捕获的内容[^;]+:匹配任意非;的字符(也就是我们要替换掉的那部分)g:全局替换,确保一行里所有匹配的dir_1/dir_2都被处理
如果要直接修改原文件(原地编辑),给sed加-i参数(GNU sed适用):
sed -i -E 's/(dir_[12]=\/some\/other\/path\/to\/a\/directory\/)[^;]+;/\1R03_0;/g' info.txt
用变量传入替换值
如果要把R03_0换成变量$rel_ver,只需要把sed命令的单引号改成双引号(让shell解析变量),直接嵌入变量即可:
rel_ver="R03_0" sed -E "s/(dir_[12]=\/some\/other\/path\/to\/a\/directory\/)[^;]+;/\1${rel_ver};/g" info.txt
原地编辑版本:
rel_ver="R03_0" sed -i -E "s/(dir_[12]=\/some\/other\/path\/to\/a\/directory\/)[^;]+;/\1${rel_ver};/g" info.txt
方法2:使用awk命令(适合复杂场景扩展)
如果需要更灵活的字符串处理逻辑,awk也是个好选择:
固定替换值
awk '{ # 循环匹配所有符合条件的子串,直到替换完 while (match($0, /(dir_[12]=\/some\/other\/path\/to\/a\/directory\/)[^;]+;/, arr)) { # 拼接字符串,替换匹配部分 $0 = substr($0, 1, RSTART-1) arr[1] "R03_0;" substr($0, RSTART+RLENGTH) } print }' info.txt
用变量传入替换值
awk通过-v参数接收shell变量,这样更安全(避免变量里的特殊字符干扰):
rel_ver="R03_0" awk -v ver="$rel_ver" '{ while (match($0, /(dir_[12]=\/some\/other\/path\/to\/a\/directory\/)[^;]+;/, arr)) { $0 = substr($0, 1, RSTART-1) arr[1] ver ";" substr($0, RSTART+RLENGTH) } print }' info.txt
如果要原地修改文件,先把输出写到临时文件,再替换原文件:
rel_ver="R03_0" awk -v ver="$rel_ver" '{ while (match($0, /(dir_[12]=\/some\/other\/path\/to\/a\/directory\/)[^;]+;/, arr)) { $0 = substr($0, 1, RSTART-1) arr[1] ver ";" substr($0, RSTART+RLENGTH) } print }' info.txt > temp.txt && mv temp.txt info.txt
测试后,你的info.txt会变成预期的内容:
/* prog_dir=/path/to/some/directory; */ dir_1=/some/other/path/to/a/directory/R03_0; dir_2=/some/other/path/to/a/directory/R03_0;
内容的提问来源于stack exchange,提问作者Foobar-naut
相关产品推荐
相关产品推荐

