在while循环中使用sed替换字符串时,如何避免额外添加换行符?
问题原因分析
你遇到的换行符重复问题,大概率是因为多次循环调用sed -i反复修改文件,导致文件的换行符被重复写入;另外read命令若未正确处理输入行格式(比如replace-oldnames.txt里有多余空格/换行),也可能让替换内容带意外换行。
解决方案
方案1:用awk一次性处理(推荐,高效且避免多次修改文件)
如果你的replace-oldnames.txt是每行对应「旧值 要追加的日期」(比如AFG20-ENV284E2 09-27-2020),直接用awk关联替换:
awk 'NR==FNR {date_map[$1]=$2; next} {print $0 "|" date_map[$0]}' replace-oldnames.txt edited.mcc.tre > temp_file && mv temp_file edited.mcc.tre
- 逻辑:先把
replace-oldnames.txt里的旧值和日期存入数组,再遍历目标文件,给每行旧值追加|和对应日期 - 用临时文件过渡是为了避免直接修改原文件时的损坏风险
如果你的replace-oldnames.txt是每行对应「旧值 完整新内容」(比如AFG20-ENV284E2 AFG20-ENV284E2|09-27-2020),则修改为:
awk 'NR==FNR {new_map[$1]=$2; next} {print new_map[$0]}' replace-oldnames.txt edited.mcc.tre > temp_file && mv temp_file edited.mcc.tre
方案2:修复原while循环
如果坚持用while+sed,做以下调整:
while read -r oldname newname; do sed -i "s/^$oldname$/$newname/" edited.mcc.tre done < replace-oldnames.txt
- 加
-r给read,防止反斜杠被转义 - 匹配模式加
^和$,确保只替换整行的旧值(避免部分匹配) - 去掉
g选项(每个旧值仅出现一次,全局替换没必要)
方案3:生成sed脚本批量执行
把replace-oldnames.txt转换成sed脚本,一次性完成替换:
# 生成sed替换脚本 sed 's/\(.*\) \(.*\)/s\/^\1$\/\2\/g/' replace-oldnames.txt > replace_script.sed # 执行替换 sed -f replace_script.sed edited.mcc.tre > temp_file && mv temp_file edited.mcc.tre
- 逻辑:把每行的「旧值 新值」转换成
s/^旧值$/新值/g的sed命令,批量执行替换
内容的提问来源于stack exchange,提问作者Hafiz Muhammad Talha Malik
相关产品推荐
相关产品推荐

