提取列并使用awk聚合值

时间:2017-09-08 08:12:23

标签: awk

我在平面文件test.txt中有以下内容

cat test.txt
2017-08-26 15:38:51.4,1.6814,DEV,TEST
2017-08-26 15:38:51.4,0.53080004,DEV,TEST
2017-08-26 15:38:51.4,1.7757,DEV,TEST
2017-08-26 15:38:51.4,0.5666,DEV,TEST
2017-08-26 15:38:55.324,0.465,DEV,TEST
2017-08-26 15:38:55.324,0.4734,DEV,TEST
2017-08-26 15:38:55.324,1.6006,DEV,TEST
2017-08-26 15:38:55.324,0.4886,DEV,TEST
2017-08-26 15:38:55.324,1.6165,DEV,TEST
2017-08-26 15:38:55.324,0.46879998,DEV,TEST
2017-08-26 15:38:55.324,1.5161,DEV,TEST
2017-08-26 15:38:55.324,3.1766,DEV,TEST
2017-08-26 15:38:55.324,1.5461,DEV,TEST
2017-08-26 15:38:55.324,1.5679,DEV,TEST
2017-08-26 15:38:55.324,1.5355,DEV,TEST
2017-08-26 15:38:55.324,0.49389997,DEV,TEST
2017-08-26 15:38:55.324,0.50909996,DEV,TEST
2017-08-26 15:38:55.325,1.7934,DEV,TEST
2017-08-26 15:38:55.325,3.005,DEV,TEST
2017-08-26 15:38:55.325,0.6599,DEV,TEST
2017-08-26 15:38:55.325,0.5711,DEV,TEST
2017-08-26 15:38:55.325,1.5683999,DEV,TEST

我需要以下输出

2017-08-26 15:38:51  4.5528
           15:38:55  23.0402

其中15:38:51是截断毫秒的时间戳,4.5528是对应于15:38:51时间戳的所有值的总和

与15:38:55相同的是时间戳,截断时间为毫秒,23.0402是与15:38:55时间戳对应的所有值的总和

我尝试了这个awk命令

$

 awk -F ".," '{a[$1] += $2} END{for (i in a) print i, a[i]}' test.txt

2017-08-26 15:38:51. 4.5528
2017-08-26 15:38:55.32 23.0402

但输出不符合预期。

它应该在第一列中显示一次日期 第二列应该具有截断日期的相应时间戳,并且第三列中的时间戳下的所有相应值的总和

3 个答案:

答案 0 :(得分:0)

您可以使用以下awk脚本:

program.awk

BEGIN {
    FS=","
    OFS=" "
}
{
    sub(/\..*$/,"",$1)
    split($1,dt," ")
    d=dt[1]
    t=dt[2]
    if(!prv_t) {
        prv_t = t
    }

    if(d!=prv_d) {
        prv_d = d
        f = 1
    }

    if(t!=prv_t) {
        if(f) {
            print prv_d,prv_t,s
            f = 0
        } else {
            print "              ",prv_t,s
        }
        prv_t = t
        s = 0
    }
    s+=$2
}

END {
    if(f) {
        print prv_d,prv_t,s
        f = 0
    } else {
        print "          ",prv_t,s
    }
}

这样称呼:

awk -f program.awk input_file

答案 1 :(得分:0)

awk 解决方案:

awk -F'[[:space:],]' '{ a[$1, substr($2,1,index($2,".")-1)]+= $3 }
     END{ for(k in a) { 
          split(k, keys, SUBSEP); 
          printf "%-10s %s %s\n",(!i++? keys[1]:""), keys[2], a[k] } 
     }' file
  • -F'[[:space:],]' - 复合字段分隔符

  • substr($2,1,index($2,".")-1) - 在.之后截断 time 值的结尾部分(即15:38:55.325变为15:38:55

  • a[$1, substr($2,1,index($2,".")-1)]+= $3 - 汇总每个日期时间序列的值

  • split(k, keys, SUBSEP) - 按分隔符

  • 拆分索引序列
  • (!i++? keys[1]:"") - 仅在第一个字段的第一行打印日期值

输出:

2017-08-26 15:38:51 4.5545
           15:38:55 23.0559

答案 2 :(得分:0)

尝试跟踪awk一次,让我知道这是否对你有帮助。

awk -F'[ .,]' '
{
  a[$1,$2]+=$4"."$5
}
END{
  for(i in a){
     split(i, check," ");
     if(check[1]==prev){
        print "\t  ",check[2],a[i]
}
     else{
        print i,a[i]
};
     prev=check[1]
}
}
' SUBSEP=" "   Input_file

输出如下。

2017-08-26 15:38:51 4.5545
           15:38:55 23.0559