【问题标题】:How to group by column values into Row and column header and then sum the value如何按列值分组到行和列标题,然后对值求和
【发布时间】:2016-12-20 11:21:48
【问题描述】:

下面是我的输入输出.txt文件。

我想按StatusDateMethod 的数据分组。 然后根据StatusDateMethod 求和。

Input.txt

No,Date,MethodStatus,Key,StatusDate,Hit,CallType,Method,LastMethodType
112,12/15/16,Suceess,Geo,12/15/16,1,Static,GET,12/15/16
113,12/18/16,Suceess,Geo,12/18/16,1,Static,GET,12/18/16
114,12/19/16,AUTHORIZED,Geo,12/19/16,1,Static,GET,12/19/16
115,12/19/16,AUTHORIZED,Geo,12/19/16,1,Static,GET,12/19/16
116,12/19/16,Suceess,Geo,12/19/16,1,Static,PUT,12/19/16
117,12/19/16,Suceess,Geo,12/19/16,1,Static,PUT,12/19/16
118,12/19/16,Waiting,Geo,12/19/16,1,Static,GET,12/19/16
119,12/19/16,AUTHORIZED,Geo,12/19/16,1,Static,GET,12/19/16
120,12/17/16,Suceess,Geo,12/17/16,1,Static,GET,12/17/16
121,12/17/16,Suceess,Geo,12/17/16,1,Static,GET,12/17/16
130,12/16/16,Suceess,Geo,12/16/16,1,Static,GET,12/16/16

Out.txt

StatusDate,12/15/16,12/16/16,12/17/16,12/17/16,12/18/16,12/19/16,12/19/16,12/19/16,12/19/16,12/19/16,12/19/16,Grand Total
GET,1,1,1,1,1,1,1,1,1,,,9
PUT,,,,,,,,,,1,1,2
Grand Total,1,1,1,1,1,1,1,1,1,1,1,11

我使用awk 并通过awk -F, '{if($8=="GET") print }' 拆分数据,然后计算总和值。 由于文件很大,所以会有延迟。

是否可以一步完成所有事情?那么文件操作会减少吗?

【问题讨论】:

  • 你能展示一些这样做的代码吗?否则,怎么会有人知道如何提高效率?
  • 您要求和什么?您如何获取 Out.txt 中的值,例如 12/17/16 上的 GET1 尽管此 StatusDate 有两条输入记录?

标签: linux shell unix awk sed


【解决方案1】:
awk -F ',' '
   /GET/{ Get[ $2]++}
   /PUT}{ Put[ $2]++}
   {Total[$2]++}

   END {
     printf( "StatusDate')
     for (d in Total) printf( ",%s", d)
     printf( "\nTotal GET")
     for (d in Total) printf( ",%d", Get[d])
     printf( " PUT")
     for (d in Total) printf( ",%d", Put[d])
     printf( " Grand Total")
     for (d in Total) printf( ",%d", Total[d])
     printf( "\n")
     }
   ' Input.txt
  • 将数据存储在每行 3 个数组中
  • 几个循环在最后显示结果

【讨论】:

    【解决方案2】:

    您可以使用关联数组来跟踪聚合。

    NR == 1 {
        next
    }
    
    $8 == "GET" {
        Get[$2]++
        g++
        Total[$2]++
        next
    }
    
    $8 == "PUT" {
        Put[$2]++
        p++
        Total[$2]++
        next
    }
    
    END {
        printf( "StatusDate")
        for (d in Total) printf( ",%s", d)
        printf( ",Grand Total\nGET")
        for (d in Total) printf( ",%d", Get[d])
        printf( ",%d\nPUT", g)
        for (d in Total) printf( ",%d", Put[d])
        printf( ",%d\nGrand Total",p)
        for (d in Total) printf( ",%d", Total[d])
        printf( ",%d\n",g+p)
    }
    

    【讨论】:

      【解决方案3】:
      $ awk -F, 'NR==1 {printf "%s",$8$2; t="Total"; v[t]; next} 
                       {d[$2]; v[$8]; a[$2,$8]++; a[$2,t]++} 
                 END   {n=asorti(d,ds); 
                        for(i=1;i<=n;i++) printf "%s", FS ds[i]; 
                        print ""; 
                        for(k in v) 
                          {printf "%s", k; 
                           for(i=1;i<=n;i++) printf "%s", FS a[ds[i],k]; 
                           print ""}}' file
      
      
      MethodDate,12/15/16,12/16/16,12/17/16,12/18/16,12/19/16
      PUT,,,,,2
      GET,1,1,2,1,4
      Total,1,1,2,1,6
      

      【讨论】:

      • 输出与预期结果不匹配,总值不正确
      猜你喜欢
      • 1970-01-01
      • 2018-10-17
      • 2020-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-01
      • 2021-05-13
      相关资源
      最近更新 更多