sed批量替换同一文件内容时重复写入问题求助
解决sed循环替换导致文件重复的问题
兄弟,你这问题我太熟了——循环里用>>追加sed处理后的内容,可不就每次都把整个hosts文件复制一遍嘛!200次循环下来,sample自然就有200份内容,每份只改了一处。给你两个靠谱的解决办法:
方法一:迭代修改目标文件(简单直接)
先把原始hosts文件复制到sample作为初始版本,然后每次循环都直接在sample上原地修改,这样每次都是基于上一次的修改结果继续操作,不会重复复制整个文件:
# 先复制原始文件作为初始样本 cp hosts sample # 循环读取替换规则 cat partthree | while read LINE do hostnam=$(echo "$LINE" | awk '{print $1}') echo "$hostnam" # 直接用grep读文件,不用less,更高效 a=$(grep "$hostnam" -A5 hosts | grep -i md5sum | awk '{print $2}') b=$(grep "$hostnam" partthree | awk '{print $2}') echo "$a" echo "$b" # GNU sed原地修改,macOS等BSD系统要写成 sed -i '' "s/$a/$b/g" sample sed -i "s/$a/$b/g" sample done
方法二:批量生成替换规则(高效推荐)
如果hosts文件比较大,多次原地修改效率不高,可以先把所有替换规则整理成一个sed脚本,然后一次性处理原始文件,只读写文件一次:
# 生成sed替换脚本,每行一条替换规则 cat partthree | while read LINE do hostnam=$(echo "$LINE" | awk '{print $1}') a=$(grep "$hostnam" -A5 hosts | grep -i md5sum | awk '{print $2}') b=$(grep "$hostnam" partthree | awk '{print $2}') # 用#作为分隔符,避免a/b里有/时出错 echo "s#$a#$b#g" done > replace.sed # 用生成的脚本一次性处理hosts到sample sed -f replace.sed hosts > sample # 可选:删除临时脚本 rm replace.sed
额外小提示
- 变量引用记得用双引号包裹,比如
echo "$LINE",避免空格或特殊字符导致解析错误; - 别用
less来读文件传参,直接用grep读取目标文件就行,效率更高。
内容的提问来源于stack exchange,提问作者mayank arora
相关产品推荐
相关产品推荐

