如何用sed将两个模式间的指定字段替换为其他文件内容?
替换hosts文件中指定标记间的IP为外部文件内容
问题描述
我有一个hosts文件,内容如下:
#ansible_python_interpreter=/usr/bin/python3 [win] #s1 192.168.1.148 #s2
希望将#s1和#s2之间的IP替换为另一个名为tmp_ip文件中的IP地址,目标效果示例:
#ansible_python_interpreter=/usr/bin/python3 [win] #s1 127.0.0.1 #s2
当前用固定IP的sed命令可实现替换,但需要改成读取外部文件的IP:
sed -e '/#s1/,/#s2/c\#s1\n127.0.0.12\n\#s2' hosts
解决方案
假设tmp_ip文件中存储了目标IP(无多余无关内容,若有多行可先提取指定行),以下是两种可行方法:
方法1:sed结合变量替换
先读取tmp_ip中的IP存入变量,再用sed精准替换目标位置:
# 读取tmp_ip中的IP(如果是多行取第一行,用head -n1 tmp_ip) new_ip=$(cat tmp_ip) # 执行替换 sed "s/\(#s1 \)[0-9.]\+\( #s2\)/\1${new_ip}\2/" hosts
如果需要原地修改hosts文件,添加-i参数(部分系统需用-i.bak生成备份文件):
new_ip=$(cat tmp_ip) sed -i "s/\(#s1 \)[0-9.]\+\( #s2\)/\1${new_ip}\2/" hosts
核心逻辑:用正则匹配#s1 和 #s2之间的IP段,捕获前后标记后插入新IP。
方法2:awk实现替换
借助awk的变量传递和字符串替换功能:
awk -v new_ip="$(cat tmp_ip)" '{sub(/(#s1 )[0-9.]+( #s2)/, "\1" new_ip "\2")}1' hosts
若要原地修改,通过临时文件中转:
awk -v new_ip="$(cat tmp_ip)" '{sub(/(#s1 )[0-9.]+( #s2)/, "\1" new_ip "\2")}1' hosts > temp_host && mv temp_host hosts
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

