高效筛选大型CSV:保留MacAddress匹配指定列表的行
高效筛选超大型CSV文件的方案
针对你5亿行的CSV1文件,需要保留MacAddress列存在于CSV0中的行,以下是几个高效的解决方案,避免加载整个大文件到内存:
方案1:使用awk(最快的命令行方案)
awk是处理文本文件的高效工具,采用流式处理,无需加载全量数据到内存。
基础命令(适用于无特殊格式的CSV)
awk -F ',' 'NR==FNR {macs[$1]=1; next} FNR==1 || macs[$2]' CSV0.csv CSV1.csv > output.csv
解释:
NR==FNR:仅处理第一个输入文件(CSV0),将每个MAC地址存入关联数组macsFNR==1:保留CSV1的表头行macs[$2]:检查CSV1的第二列(MacAddress)是否在macs数组中,存在则输出该行
处理带引号的CSV(如字段包含逗号)
如果CSV1存在带引号的字段,使用gawk的FPAT参数正确解析CSV格式:
gawk 'BEGIN {FPAT = "([^,]+)|(\"[^\"]+\")"} NR==FNR {macs[$1]=1; next} FNR==1 || macs[$2]' CSV0.csv CSV1.csv > output.csv
方案2:Python脚本(适合需要集成到现有Python工作流的场景)
通过逐行读取CSV1,结合set的O(1)查找特性,避免内存溢出:
import csv # 加载CSV0的MAC地址到集合(查找效率远高于列表) mac_set = set() with open("CSV0.csv", "r") as f_mac: for line in f_mac: mac = line.strip() if mac: mac_set.add(mac) # 流式处理CSV1,写入符合条件的行 with open("CSV1.csv", "r") as f_in, open("output.csv", "w", newline="") as f_out: reader = csv.reader(f_in) writer = csv.writer(f_out) # 写入表头并定位MacAddress列索引 header = next(reader) writer.writerow(header) mac_col_idx = header.index("MacAddress") # 逐行检查并输出 for row in reader: if row[mac_col_idx] in mac_set: writer.writerow(row)
方案3:grep命令(备选,适合简单场景)
将CSV0的MAC转换为精确匹配第二列的正则模式,再过滤:
# 生成匹配第二列MAC的正则模式 sed 's/^/^.*,/;s/$/,/' CSV0.csv > mac_patterns.txt # 先写入表头,再追加匹配的行 head -n 1 CSV1.csv > output.csv grep -f mac_patterns.txt CSV1.csv >> output.csv
注:此方法效率略低于awk,且不适用于带引号的复杂CSV格式。
内容的提问来源于stack exchange,提问作者Marmotte73
相关产品推荐
相关产品推荐

