You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Shell脚本中提取两个CSV文件的差异数据

Shell提取两个CSV文件差异数据的实现方案

先提前统一两个文件的基础格式,避免匹配异常:如果是Windows导出的CSV先执行dos2unix 文件.csv转换换行符,提前过滤掉无意义的末尾空行可以用grep -v '^$' 原文件.csv > 处理后文件.csv。


场景1:不要求保留原行顺序,整行完全匹配找差异

优先用comm命令,处理大文件速度最快,注意comm要求输入内容是排序状态:

  • 如果CSV没有表头,直接执行以下命令即可:
# 先对两个文件排序生成临时文件
sort a.csv > a_sorted.tmp
sort b.csv > b_sorted.tmp
# 提取所有差异:输出结果中无缩进的是a.csv独有内容,带一个制表符缩进的是b.csv独有内容
comm -3 a_sorted.tmp b_sorted.tmp > diff_raw.csv
# 如果不需要缩进区分,直接把所有差异行平铺输出
comm -3 a_sorted.tmp b_sorted.tmp | sed 's/^\t//' > diff_result.csv
# 删除临时文件
rm *.tmp
  • 如果CSV带表头,先单独提取表头,跳过表头再对比,最后拼接结果:
# 取第一个文件的表头作为结果文件表头
head -n 1 a.csv > diff_result.csv
# 跳过两个文件的第一行表头,排序后对比
tail -n +2 a.csv | sort > a_no_header.tmp
tail -n +2 b.csv | sort > b_no_header.tmp
comm -3 a_no_header.tmp b_no_header.tmp | sed 's/^\t//' >> diff_result.csv
rm *.tmp

场景2:需要保留原文件的行顺序找差异

用awk实现,不需要提前排序,执行效率也很高:

# 提取所有只在a.csv中存在、b.csv中不存在的行,保留a.csv里的原有顺序
awk 'NR==FNR{record[$0]=1;next} !record[$0]' b.csv a.csv > only_in_a.csv
# 提取所有只在b.csv中存在、a.csv中不存在的行,保留b.csv里的原有顺序
awk 'NR==FNR{record[$0]=1;next} !record[$0]' a.csv b.csv > only_in_b.csv
# 合并两个结果就是全量差异
cat only_in_a.csv only_in_b.csv > all_diff.csv

如果不需要整行匹配,只按指定字段判断是否为同一条数据(比如按第1列的用户ID匹配),只需要修改awk里的数组键即可,比如按第1列(逗号分隔)匹配a独有的行:

awk -F ',' 'NR==FNR{record[$1]=1;next} !record[$1]' b.csv a.csv > only_in_a_by_id.csv

特殊场景注意

如果你的CSV里存在引号包裹的带逗号字段(比如"张三,运营部",1001这种格式),不要用上面简单的逗号分隔逻辑,会出现字段拆分错误,建议用专门的CSV处理工具(比如csvkit)做对比,避免匹配结果出错。

内容的提问来源于stack exchange,提问作者N I R M A L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 22:42:28