如何通过列标题使用awk替换不同CSV文件中的指定列?
问题分析
1. var2为空的原因
你写的awk命令没指定CSV的分隔符(默认是空格),但CSV是用逗号分隔的,所以$1=="index2"根本匹配不到标题行。比如test1.csv标题行要是col1,index2,col3,默认分割下$1是col1,index2是$2,自然触发不了p=1,var2就空了。
2. 列替换逻辑完全错误
你后面的awk脚本逻辑根本没实现替换需求:
- 把var1(test4.csv里匹配行之后的所有内容)塞给数组a的每个元素,等于所有行的
a[NR]都是一整坨内容,完全没用。 - 处理test1.csv时只是给
varr变量赋值,但根本没修改原行的字段,最后直接打印整行,当然看不到替换效果。
解决方案
别用bash变量绕弯子,直接用awk搞定整个逻辑,可靠还通用。核心思路很简单:
- 先从两个文件的标题行找到要替换的列的位置
- 按行对应把test4.csv的目标列换成test1.csv的对应列
假设两个CSV都有标题行,且数据行数量一致,直接用这个脚本:
BEGIN { FS=OFS="," } # 先处理test4.csv,存下所有行并找到目标列索引 FNR==NR { if (FNR == 1) { for (i=1; i<=NF; i++) { if ($i == "2xedni") target_col = i } } lines[FNR] = $0 next } # 再处理test1.csv,替换对应列 { if (FNR == 1) { for (i=1; i<=NF; i++) { if ($i == "index2") source_col = i } print lines[1] # 打印test4的标题行 next } # 拆分test4的当前行,替换目标列 split(lines[FNR], arr, OFS) arr[target_col] = $source_col # 拼回去打印 for (j=1; j<=length(arr); j++) { printf "%s%s", arr[j], (j==length(arr) ? "\n" : OFS) } }
把代码存成replace_col.awk,然后执行:
awk -f replace_col.awk test4.csv test1.csv > test5.csv
补充说明
- 要是CSV用的不是逗号分隔,改
BEGIN { FS=OFS="," }里的符号就行 - 要是两个文件数据行数量不一样,test1多的行会被忽略,test4多的行会原样输出
- 如果CSV里有带逗号的引号字段(比如
"hello,world"),这个基础脚本搞不定,得用专门的CSV解析工具或者更复杂的awk逻辑
内容的提问来源于stack exchange,提问作者LadyG
相关产品推荐
相关产品推荐

