繁体   English   中英

加入2个CSV文件

[英]joining 2 csv files

join.awk

#!/bin/awk -f
BEGIN {
    FS=OFS=",";
    print "ozone,particullate_matter,carbon_monoxide,sulfure_dioxide,nitrogen_dioxide,longitude,latitude,timestamp,avgMeasuredTime,avgSpeed,medianMeasuredTime,Distance between 2 points,duration of measurements,ndt in kmh"
}
NR==FNR && NR>1 {
    a[$8]=$1 FS $2 FS $3 FS $4 FS $5 FS $6 FS $7
}
FNR>1 {
if ($6 in a) {
    split(a[$6],data,FS);
    if ((data[6]==$11 || data[6]==$13) && (data[7]==$10 || data[7]==$12)) {
         print data[1],data[2],data[3],data[4],data[5],data[6],data[7],$6,$2,$3,$5,$14,$15,$16
        }
    }
}

我有这段代码合并两个具有3个公共列的csv文件。 我在stackoverflow的人们的帮助下获得了此代码。

Inputfile1

ozone,particullate_matter,carbon_monoxide,sulfure_dioxide,nitrogen_dioxide,lon    gitude,latitude,timestamp
101,94,49,44,87,10.1050,56.2317,1406831700
106,97,48,47,86,10.1050,56.2317,1406832000
107,95,49,42,85,10.1050,56.2317,1406832300
103,90,51,44,87,10.1050,56.2317,1406832600

Inputfile2

status,avgMeasuredTime,avgSpeed,extID,medianMeasuredTime,TIMESTAMP,vehicleCount,_id,REPORT_ID,Lat1,Long1,Lat2,Long2,Distance between 2 points,duration of measurements,ndt in kmh
OK,74,50,668,74,1406831700,5,20746220,158324,56.2317,10.1050,56.2258,10.1166,1030,52,71
OK,73,50,668,73,1406859900,6,20746392,158324,56.2317,10.1050,56.2258,10.1166,1030,52,71
OK,61,60,668,61,1406832300,4,20746723,158324,56.2317,10.1050,56.2258,10.1166,1030,52,71
OK,61,60,668,61,1406860500,1,20747172,158324,56.2317,10.1050,56.2258,10.1166,1030,52,71

产量

ozone,particullate_matter,carbon_monoxide,sulfure_dioxide,nitrogen_dioxide,longitude,latitude,timestamp,avgMeasuredTime,avgSpeed,medianMeasuredTime,Distance between 2 points,duration of measurements,ndt in kmh
101,94,49,44,87,10.1050,56.2317,1406831700,74,50,74,1030,52,71
107,95,49,42,85,10.1050,56.2317,1406832300,61,60,61,1030,52,71

每个输入文件有1300000+行。

当我运行此命令时, awk -f join.awk Inputfile1.csv Inputfile2.csv

我只打印标题。 但是此代码适用于较小的文件。 请帮忙

您可以使用join合并两个文件,然后打印出所需的列:

join -j 1 -t ',' <( awk '{printf "%d,%s\n", NR, $0}' < test_file1 ) <( awk '{printf "%d,%s\n", NR, $0}' < test_file2 ) | awk -F ',' ' {print $2 FS $3}'

让我们分解一下:

首先,我们为每行加上行号和逗号作为前缀:

awk '{printf "%d,%s\n", NR, $0}' < test_file1

我们使用bash重定向将输出发送到join命令中。

# Join on field 1 (-j 1) using a seperator comma ( -t , )
join -j 1 -t ',' file_1 file_2

最后,我们将其通过管道传输到awk以打印出我们的字段:

awk -F ',' ' {print $2 FS $3 FS $8}'

好吧,如果代码可以正常工作并且文件很好,则可以合理地假设哈希到a的数据文件太大。 您可以拆分Inputfile1并使用Inputfile2分别运行每个部分,例如:

$ awk -f  join.awk Inputfile1_piece1.csv Inputfile2.csv
$ awk -f  join.awk Inputfile1_piece2.csv Inputfile2.csv
$ awk -f  join.awk Inputfile1_piece3.csv Inputfile2.csv
$ awk -f  join.awk Inputfile1_piece_etc.csv Inputfile2.csv

根据您的数据,尤其是$8 ,您可能需要处理重复数据; a[$8]=$1 FS $2 ...删除时间戳重复的行,其中随机拆分可能导致重复。 在拆分之前进行排序可以减少更改,但不会完全删除,因此请检查每个文件的第一个和最后一个时间戳是否匹配。

但:

我确实编写了以下awk脚本(更多是为了满足自己的好奇心),但是您可以尝试将其用于数据。 假定文件按时间戳排序。 它根本没有经过战斗测试,仅使用您提供的少量示例数据,并且似乎淘汰了重复的记录,但是不确定这是好是坏。

它从2个文件中读取记录,并且不会将它们散列到内存中。 尽管来自其他文件的时间戳小于来自其他文件的时间戳,但请不要浪费行数(因此必须对时间戳进行排序)。

BEGIN {FS=OFS="," }
NR==1 {                             # read, form and print header
    if(0>=getline line < file1)     
        exit
    print line,$2,$3,$5,$(NF-1),$NF
    next                            # and deal (off) with the first records
}
$6>=a[8] {
    while((getline line < file1) > 0 && (n=split(line,a)) && a[8] < $6)
        ;
    if(a[8]==$6 && (a[6]==$11 || a[6]==$13) && (a[7]==$10 || a[7]==$12) && n>0)
        print line,$2,$3,$5,$(NF-1),$NF
}

运行它( Inputfile1已经在时间戳上进行了排序,因此可以通过getline Inputfile2并非如此,因此可以通过进程替换进行排序。请记住对您的数据文件进行排序):

$ awk -v file1="Inputfile1" -f foo.awk <(sort -t, -k6n Inputfile2)
ozone,particullate_matter,carbon_monoxide,sulfure_dioxide,nitrogen_dioxide,longitude,latitude,timestamp,avgMeasuredTime,avgSpeed,medianMeasuredTime,duration of measurements,ndt in kmh
101,94,49,44,87,10.1050,56.2317,1406831700,74,50,74,52,71
107,95,49,42,85,10.1050,56.2317,1406832300,61,60,61,52,71

可能会有一百万个半错误,使用时需您自担风险,如果这样做,请验证,确认和验证结果。 它只写到stdout,所以它不应该破坏任何东西:D。 (所有人)如果您发现一些不合逻辑的地方,请随时进行修复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM