例如我有两个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/