如何用awk快速基于小文件列值匹配多份大文件并按规则输出
原有脚本的核心问题
你当前写的awk脚本存在两个严重问题,无法满足大数据量的处理要求:
- 匹配效率极低:对每一行CLEANUP文件都遍历整个50万规模的hash表做匹配,1000万行总运算量达到5e11次,不可能在合理时间内跑完。
- 匹配精度缺陷:用
match($0,i)匹配整行内容,若f2字段中包含f1的数值会出现误匹配,输出结果不准。
高效实现方案
直接利用awk hash的O(1)存在性判断能力,全程仅遍历1.csv一次、所有CLEANUP文件一次,总时间复杂度为O(50万+1000万),普通家用机器也能在几分钟内跑完,且匹配精度100%准确。
最终脚本
awk ' # 处理1.csv,构建f1的hash集合 FNR == NR { # 去除行前后空格,避免空格导致匹配失败 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $0) hash[$0] = 1 next } # 提前指定CLEANUP文件的分隔符为逗号 BEGIN { FS = "," } { # 去除f1、f2前后的多余空格 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1) gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2) # 仅判断f1是否在白名单中,O(1)开销 if ($1 in hash) { # 取f2最后一位作为输出文件编号 suffix = substr($2, length($2), 1) # 输出到对应文件,保留原始格式可直接写 print $0 > (suffix ".csv") print " " $1 ", " $2 > (suffix ".csv") } } ' 1.csv CLEANUP_BC_*.csv
说明
- 输出文件最多只有10个(对应f2末位0-9),不会超出awk的打开文件数限制,无需额外处理文件关闭逻辑。
- 如果你需要完全保留CLEANUP文件中行的原始格式(包括原始空格、缩进),可以把输出行改为
print $0 > (suffix ".csv")即可。 - 执行后会在当前目录直接生成0.csv~9.csv共10个结果文件,完全符合你的需求。
内容的提问来源于stack exchange,提问作者sasikumar karuppiah
相关产品推荐
相关产品推荐

