如何将多个文件中的选定列合并到一个文件中,并对相邻行数据进行一些计算?
这是一个示例:来自多个设备的多个数据文件,每个数据文件每个月报告多个传感器的数据。所以有一个文件/设备/月,我想要一个文件/传感器。
以下是一些示例数据和预期输出。
示例数据文件device0_202105.csv
:
Date;Time;Timestamp;PM2_5;AQI;PM10;CO2
2021/05/01;00:00:49;1619827249;21.0;70;29.0;413
2021/05/01;00:10:49;1619827849;20.0;68;37.0;409
2021/05/01;00:20:49;1619828449;21.0;70;39.0;412
2021/05/03;08:10:39;1620029439;33.0;95;43.0;430
2021/05/03;08:20:39;1620030039;33.0;95;50.0;427
2021/05/03;08:30:39;1620030639;35.0;99;38.0;429
2021/05/03;08:40:39;1620031239;33.0;95;46.0;431
2021/05/03;18:10:39;1620065439;12.0;50;18.0;425
2021/05/03;18:20:39;1620066039;12.0;50;18.0;426
示例数据文件device0_202106.csv
:
Date;Time;Timestamp;PM2_5;AQI;PM10;CO2
2021/06/01;08:19:16;1622535556;19.0;66;30.0;426
2021/06/01;08:29:16;1622536156;20.0;68;33.0;454
2021/06/01;08:39:16;1622536756;24.0;76;31.0;456
2021/06/01;20:49:16;1622580556;36.0;102;32.0;447
示例数据文件device1_202105.csv
:
Date;Time;Timestamp;PM2_5;AQI;PM10;CO2
2021/05/03;11:14:59;1620040499;19.0;66;20.0;438
2021/05/03;11:15:09;1620040509;19.0;66;20.0;486
2021/05/03;11:15:19;1620040519;18.0;63;18.0;485
我想为整个可用数据周期(此处为 202105 和 202106)为每种类型的传感器(例如 CO2)创建一个文件,data-co2.csv
使用上述数据看起来像这样:
Date;Time;Device 0;Device 1
2021/05/03;10:30;429.25;469.667
2021/06/01;10:30;475.333
每个设备的数据按列报告,每个数据点是某个时间间隔内的平均值。所以一行报告原始数据的时间间隔的平均值。
我最初只考虑每个工作日只有 2 个时间间隔:早上 8:00 到 13:00 的时间间隔(标记为 10:30)和下午的时间间隔从 13:00 到 18:00(标记为 15:30 )。
我计划运行一个awk
脚本,该脚本由一个bash
循环遍历设备和周期文件的脚本启动。这是我的脚本的开始。但是,我无法写入输出文件(我应该使用-inplace
选项吗?)。我正在考虑更简单的路线:写入临时文件并稍后连接到输出文件。
#!/bin/bash
touch data-co2.csv
gawk -v device=0 -v sensor=18 -f read-data.awk device0_202105.csv data-co2.csv
#!/bin/gawk -f
BEGIN {
FS = "[;/:]";
OFS = ";";
day = 1 ;
sam = 0 ; nam = 0 ; spm = 0 ; npm = 0 ;
}
FNR==NR {
if ( $1 ~ /20[0-9]{2}/ ) {
if ( $3 != day ) {
if ( nam != 0 ) a[date";10:30"] = sam / nam ;
if ( npm != 0 ) a[date";15:30"] = spm / npm ;
day = $3 ;
sam = 0 ; nam = 0 ; spm = 0 ; npm = 0 ;
}
if ( strftime("%u", $7, 1) < 6) {
if ( $4 >= 8 && $4 <= 12 ) {
sam += $sensor ;
++nam ;
}
else if ( $4 >= 13 && $4 < 18 ) {
spm += $sensor ;
++npm ;
}
}
date = $1"/"$2"/"$3 ;
}
next ;
}
{
if ( device == 0 ) {
for ( i in a ) {
print i, a[i] ;
}
}
else {
i = $1"/"$2"/"$3";10:30" ;
j = $1"/"$2"/"$3";15:30" ;
print $0, a[i] ;
print $0, a[j] ;
}
}
请注意,每台设备上报数据的时间不同,可能会因设备故障、网络问题等原因导致数据丢失。
根据评论进行编辑。
也许不是最优雅的,但它可以完成工作。请注意,数组遍历选项形式
gawk
是确保设备的列标题与值匹配的必要条件。从您的示例输入创建的名为 1_04、2_04 和 3_02 的示例输出表单文件添加了一些日期(5 月 1 日和 2 日是周末,未选择,添加了更多天数以测试“N/A”)和一些数字崩溃(以确保匹配号码和设备)。
如您所见,它甚至会显示当整天或时间间隔没有为所有设备提供值时。但相应的日期必须在日志文件中。