大CSV文件高效匹配:AWK优化需求(20万+行)
高效处理大CSV文件的AWK解决方案
需求说明
现有两个行数超20万的CSV文件File1.csv和File2.csv,需完成以下操作:
- 当
File1的第1列等于File2的第2列,且File1的第7列等于File2的第1列时,将File2的第4列追加到File1对应行 - 若
File2的第4列为空,则追加逗号(保证输出格式统一)
当前采用AWK逐行调用shell脚本的处理方式速度极慢,需替换为高效的纯AWK实现。
高效AWK实现命令
BEGIN { FS = OFS = "," } # 先读取File2,构建匹配映射表 NR == FNR { # 用File2的第2列+第1列作为键,对应File1的第1列+第7列的匹配条件 key = $2 "," $1 # 存储第4列的值,空值则保留空字符串 map[key] = $4 next } # 处理File1的每一行 { # 生成当前行的匹配键 match_key = $1 "," $7 # 从映射表中取出对应值,无匹配则为空字符串 append_val = map[match_key] # 输出原行+追加值,OFS会自动处理逗号分隔,空值则追加逗号 print $0, append_val }
执行方式:
awk -f script.awk File2.csv File1.csv > My_output.csv
或直接单行执行:
awk 'BEGIN{FS=OFS=","} NR==FNR{key=$2","$1;map[key]=$4;next} {match_key=$1","$7;print $0, map[match_key]}' File2.csv File1.csv > My_output.csv
方案原理
- 内存映射预加载:先读取
File2.csv,将需要匹配的条件(File2第2列+第1列)作为键,第4列的值存入内存数组map,全程仅一次IO读取 - 单进程匹配输出:遍历
File1.csv时,直接通过内存数组查找匹配值,无需启动任何子进程,避免了频繁进程切换的开销 - 格式自动维护:利用AWK的
OFS(输出字段分隔符)自动处理逗号分隔,空值情况下会自动追加逗号,保证输出格式统一
原方案低效原因
原实现中,AWK每处理一行File1的数据就调用一次product.sh脚本,而脚本内部又执行grep和sed命令:
- 每一行都要启动新的shell进程,20万行就会产生20万次进程创建/销毁的开销
- 每次
grep都会全量扫描File2.csv,重复IO操作极大拖慢速度
示例文件
File1.csv
3398710422,5000,1,180000,1,,1 3301280335,801,1,0.0732,2,, 3398765402,8010,1,0.1,2,, 3398710132,801,1,1.2078,2,, 3301280033,801,1,0.0366,2,, 3201070157,7030,1,100,1,,13 3398772988,6000,1,150,2,,6 3201070157,7040,1,322122547200,1,,11 3398710122,7010,1,262076027,1,,1 3398710122,7020,1,209647227,1,,1 3201070200,7070,1,64424509440,1,, 3310080030,801,1,0.4392,2,,
File2.csv
1,3398710422,7679001, 13,3201070157,107363269,Product1 11,3201070157,107363269,Product1 1,3398710122,115615379, 6,3398772988,178969511,Product2 1,3398710212,214848153, 1,3398772987,232064121, 4,3202120151,323408705,Product3 1,3241000312,334663103, 1,3398710317,354231059, 3,3291010100,410449509,Product4 6,3261000217,428276109,Product5 5,3398700981,458493983,Product6 1,3398710222,466435383,
期望输出My_output.csv
3398710422,5000,1,180000,1,,1, 3301280335,801,1,0.0732,2,,, 3398765402,8010,1,0.1,2,,, 3398710132,801,1,1.2078,2,,, 3301280033,801,1,0.0366,2,,, 3201070157,7030,1,100,1,,13,Product1 3201070157,7040,1,322122547200,1,,11,Product1 3398710122,7010,1,262076027,1,,1, 3398710122,7020,1,209647227,1,,1, 3398772988,6000,1,150,2,,6,Product2 3202120151,2000,2,100,1,,4,Product3 3291010100,2000,2,100,1,,3,Product4 3261000217,2000,2,100,1,,6,Product5 3398700981,2000,2,100,1,,5,Product6 3201070200,7070,1,64424509440,1,,, 3310080030,801,1,0.4392,2,,,
内容的提问来源于stack exchange,提问作者alex_rvn
相关产品推荐
相关产品推荐

