使用 Awk 将时间戳数据从每秒转换为每分钟的更好方法



我正在尝试从每秒到每分钟聚合数据(取该分钟内所有值的平均值)。我的数据带有以下格式的时间戳:

date time[h:m:s-03:00],X,value
2016-05-29 15:50:33-03:00,X,561
2016-05-29 15:50:34-03:00,X,565
....

我已经用以下代码破解了答案,但我想找到一种更好、更干净的方法来做到这一点:

awk -F: 'BEGIN{
    foo_total=0;
    foo=0; }
    {
    split($4,ar,",");
    foo=ar[3];
    split($3,a,"-");
    if(a[1]~"00"){
            first_foo=ar[3]}
    if(a[1]!~"00"){
            foo_total+=ar[3]}
    foo_sum=(first_foo + foo_total);
    foo_final=foo_sum/60
    if(a[1]~"59") {printf $1":"$2","foo_final"n"; foo_total=0; first_foo=0;} }' MyFile.csv

非常感谢您的帮助!

基于Perl的方法:

$ cat testdata
2016-05-29 15:50:33-03:00,X,561
2016-05-29 15:50:34-03:00,X,565
$ perl -E 'my %arr; my %len;
           while(<STDIN>){
               m/^(d{4}-d{2}-d{2} d{2}:d{2}):d{2}-03:00,X,([0-9]*)/;
               $arr{$1} += $2; $len{$1}++;
           }
           foreach my $key (sort keys %arr) {
               print "$key-03:00,X,". ($arr{$key}/$len{$key}) . "n";
           }' < testdata 
2016-05-29 15:50-03:00,X,563

解释:

  1. 对于每行,将行拆分为字段 (m/...行)和
  2. 在分别名为arr和len的哈希中累积值和长度。
  3. 最后,打印平均值。

你可以跳过逻辑的长度部分,并将其硬编码为60。但IMO,记录每分钟的实际条目数更安全。

请查看以下awk代码:

BEGIN { total = 0; DayHour="Empty"; Min="";}
{
    if((DayHour ~ $1) && (Min ~ $2))
    {
         split($4,a,",");
         total += a[3];
    }
    else
    {
          if(DayHour !~ "Empty")
              print DayHour":"Min, total / 60;
          DayHour=$1;
          Min=$2;
          split($4,a,",");
              total = a[3];
    }
}
END {print DayHour":"Min, total / 60; }

您可以按awk -F: -f progam <data_file>运行它

最新更新