如何用sed/awk仅替换CSV最后一列内容(支持数组匹配)
CSV仅最后一列按数组规则替换的解决方案
需求概述
仅对CSV文件最后一列执行字符串替换,替换规则从两个对应文件(旧值文件、新值文件)读取并映射;需支持自定义输入输出文件名,解决原sed全局替换、单变量awk无法适配数组的问题。
问题拆解
- sed全局替换会修改所有列,不符合需求;
- 单变量awk逻辑无法批量处理数组级的替换规则;
- 规避Bash数组传递给awk的兼容性问题,直接让awk加载规则更可靠。
实现脚本
编写Bash脚本csv_replace_last_col.sh,通过awk读取规则文件构建替换映射,仅操作CSV最后一列:
#!/bin/bash # 参数校验:旧值文件、新值文件、输入CSV、输出CSV if [ $# -ne 4 ]; then echo "用法: $0 <旧值文件路径> <新值文件路径> <输入CSV路径> <输出CSV路径>" exit 1 fi OLD_VALS="$1" NEW_VALS="$2" INPUT_CSV="$3" OUTPUT_CSV="$4" # awk核心逻辑:构建替换数组,仅替换最后一列 awk -F ',' -v OFS=',' ' # 读取旧值文件,按行号存入数组 NR == FNR { old[NR] = $0 next } # 读取新值文件,按行号对应存入数组 FNR == NR { new[NR] = $0 next } # 处理CSV:遍历替换数组,仅修改最后一列$NF { for (i in old) { # 若需精确整列替换,替换为:if ($NF == old[i]) $NF = new[i] gsub(old[i], new[i], $NF) } print $0 } ' "$OLD_VALS" "$NEW_VALS" "$INPUT_CSV" > "$OUTPUT_CSV"
示例验证
规则文件
old_values.txt(待替换旧字符串):
apple banana
new_values.txt(对应新字符串):
APPLE BANANA
输入CSV(input.csv):
id,name,fruit 1,Alice,apple 2,Bob,banana 3,Charlie,apple
执行命令:
chmod +x csv_replace_last_col.sh ./csv_replace_last_col.sh old_values.txt new_values.txt input.csv output.csv
输出CSV(output.csv):
id,name,fruit 1,Alice,APPLE 2,Bob,BANANA 3,Charlie,APPLE
自定义调整
- 分隔符适配:若CSV用制表符或其他分隔符,修改
-F ','和OFS=','为对应值(如-F '\t'); - 精确匹配替换:若需整列完全匹配才替换,将awk中的
gsub(old[i], new[i], $NF)替换为:if ($NF == old[i]) $NF = new[i] - 正则特殊字符处理:若旧值含
.、*等正则元字符,改用index函数实现非正则替换:for (i in old) { idx = index($NF, old[i]) if (idx != 0) { $NF = substr($NF, 1, idx-1) new[i] substr($NF, idx+length(old[i])) } }
内容的提问来源于stack exchange,提问作者user183980
相关产品推荐
相关产品推荐

