perl - 将非常大的 csv 文件与公共(public)列合并

标签 perl unix join csv awk

例如我有两个csv文件, 0.csv

100a,a,b,c,c
200a,b,c,c,c
300a,c,d,c,c

和 1.csv

100a,Emma,Thomas
200a,Alex,Jason
400a,Sanjay,Gupta
500a,Nisha,Singh

我希望输出像

100a,a,b,c,c,Emma,Thomas
200a,b,c,c,c,Alex,Jason
300a,c,d,c,c,0,0
400a,0,0,0,0,Sanjay,Gupta
500a,0,0,0,0,Nisha,Singh

如何在 Unix shell 脚本或 Perl 中执行此操作?我知道 unix 的“join”命令,它可以很好地处理小文件。例如,为了得到我的结果,我可以这样做

join -t , -a 1 -a 2 -1 1 -2 1 -o 0 1.2 1.3 1.4 1.5 2.2 2.3 -e "0" 0.csv 1.csv

但这对我的目的来说是不可行的,因为我的实际数据文件有超过一百万列(总数据大小以千兆字节为单位),因此我的 unix 命令也将超过一百万个字符。这可能是最令人头疼的问题,因为低效代码很快就会陷入困境。

另请注意,每当有缺失数据时,我都需要占位符字符“0”。这使我无法简单地使用它

join -t , -a 1 -a 2 -1 1 -2 1 0.csv 1.csv

也是一名初学者 Perl 程序员,所以非常欢迎提供一些详细信息。我希望解决方案是 perl 或 shell 脚本,但实际上任何有效的方法都可以。

最佳答案

如果您可以为每个文件添加一个标题,那么您可以使用 tabulator解决问题。示例:

0.csv:

key,letter_1,letter_2,letter_3,letter_4
100a,a,b,c,c
200a,b,c,c,c
300a,c,d,c,c

1.csv:

key,name_1,name_2
100a,Emma,Thomas
200a,Alex,Jason
400a,Sanjay,Gupta
500a,Nisha,Singh

然后tbljoin -lr -n 0 0.csv 1.csv产生

key,letter_1,letter_2,letter_3,letter_4,name_1,name_2
100a,a,b,c,c,Emma,Thomas
200a,b,c,c,c,Alex,Jason
300a,c,d,c,c,0,0
400a,0,0,0,0,Sanjay,Gupta
500a,0,0,0,0,Nisha,Singh

请注意(与纯 unix join 命令相反),输入文件不需要排序;此外,您无需担心内存消耗,因为实现是基于 unix 排序的,并且会对大文件采用基于文件的合并排序。

关于perl - 将非常大的 csv 文件与公共(public)列合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12041966/

相关文章:

shell - 删除 CR 行终止符

linux - 在 UNIX 中下载 SSL 证书

c - Perl 到 C 到 DLL

perl - Perl 的 NYTProf 分析器

perl - 是否有用 Perl 编写的类似 cron 的服务?

MySQL JOIN + WHERE + GROUP BY

MySQL 查询以检索在多对多关系中具有完全匹配的项

windows - 我如何在 Perl 中使用 Control D?

ubuntu - 无法在 Ubuntu 上启动 cassandra 服务?

mysql - SQL 根据连续日期获取值的变化,并按值分组