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
我只得到标题打印。但是这段代码适用于较小的文件。 请帮忙
答案 0 :(得分:0)
您可以使用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}'
答案 1 :(得分:0)
好吧,如果代码有效并且文件很好,那么假设数据文件散列到<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>React, Babel, Webpack 2</title>
</head>
<body class="container">
<div id="app"></div>
<script src="jquery.timeago.js"></script>
<script src="client.min.js"></script>
</body>
</html>
太大是合乎逻辑的。您可以拆分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
...删除具有重复时间戳的行,其中随机拆分可能导致重复。在拆分之前进行排序会减少其更改但不会完全删除它,因此请检查每个文件的第一个和最后一个时间戳以进行匹配。
<强> BUT:强>
我确实编写了以下awk脚本(更多是为了满足自己的好奇心),但您可以尝试使用它来处理数据。它假定文件按时间戳排序。它根本没有经过战斗测试,只有你提供的小样本数据,似乎要清除重复的记录,不确定这是好还是坏。
它从2个文件中读取记录,并且不会将它们哈希到内存中。虽然来自其他文件的时间戳小于另一个文件的时间戳,但要保持浪费行(因此必须订购时间戳)。
a[$8]=$1 FS $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
可能有一百五十个错误,使用风险自负,如果您这样做,请验证,验证,验证结果。它只写入stdout所以它不应该破坏任何东西:D。 (每个人)如果你看到一些不合逻辑的话,请随意修理它。