perl – 使用公共列合并非常大的csv文件
发布时间:2020-12-15 21:16:54 所属栏目:大数据 来源:网络整理
导读:例如,我有两个csv文件, 0.csv 100a,a,b,c,c200a,c300a,d,c 和 1.csv 100a,Emma,Thomas200a,Alex,Jason400a,Sanjay,Gupta500a,Nisha,Singh 我希望输出像 100a,Jason300a,0400a,Singh 我如何在Unix shell脚本或Perl中执行此操作?我知道unix“join”命令,这对
例如,我有两个csv文件,
0.csv 100a,a,b,c,c 200a,c 300a,d,c 和 100a,Emma,Thomas 200a,Alex,Jason 400a,Sanjay,Gupta 500a,Nisha,Singh 我希望输出像 100a,Jason 300a,0 400a,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脚本,但实际上任何有效的方法都可以. 解决方法
你也可以用awk做到这一点.
确定两个文件中最宽行的长度并将其保存为max0和max1: awk -F,' ARGIND == 1 && NF > max0 { max0 = NF } ARGIND == 2 && NF > max1 { max1 = NF } END { print max0,max1 } ' 0.csv 1.csv | read max0 max1 使用此awk脚本进行连接: foo.awk BEGIN { max1-- FS = OFS = "," } ARGIND == 1 { A[$1] = $2 # Copy columns from first file to key for(i=3; i<=NF; i++) A[$1] = A[$1] FS $i # Pad until we have max0 columns for( ; i<=max0; i++) A[$1] = A[$1] FS "0" } ARGIND == 2 { # Pad rows which are only in second file if(A[$1] == "") { A[$1] = 0 for(i=3; i<=max0; i++) A[$1] = A[$1] FS "0" } # Copy columns from second file to key for(i=2; i<=NF; i++) A[$1] = A[$1] FS $i # Pad until we have max1 columns for( ; i<=max1; i++) A[$1] = A[$1] FS "0" } END { for(key in A) { # Pad rows which are only in first file split(A[key],fields,",") for(i=1; i <= max0+max1-length(fields)-1; i++) A[key] = A[key] FS "0" # Finally print key and accumulated column values print key,A[key] } } 运行: awk -f foo.awk -v max0=$max0 -v max1=$max1 0.csv 1.csv | sort -n 用-v传入最宽的行值.输出来自哈希并且未排序,因此在显示之前排序-n. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |