使用awk对数据进行分组和计算

use awk to group and calculate data

我想使用 gawk 对一些数据进行分组并对 csv 文件进行计算。

原始样本数据:

2600,AEIOU-2600,stack,2,04/01/2015,C C S,S,10.65
2600,AEIOU-2600,stack,3,04/20/2015,C C R,S,100
2600,AEIOU-2600,stack,1,04/28/2015,C C R,S,1.07
2600,AEIOU-2600,stack,4,04/29/2015,C C R,S,200
2601,"over, L.P. - 00001",stack,0,04/01/2015,C C S,s,50
2601,"over, L.P. - 00001",stack,1,04/01/2015,C C S,s,16.43
2601,"over, L.P. - 00001",stack,2,04/10/2015,D C S,s,17.16
2602,UEIA,stack,2,04/19/2015,C C S,s,500
2602,UEIA,stack,2,04/20/2015,C C S,s,50
2602,UEIA,stack,1,04/28/2015,C C S,s,10
2602,UEIA,stack,2,04/28/2015,C C S,s,30
2602,UEIA,stack,2,04/29/2015,C C S,s,40
2603,EDM,stack,1,04/01/2015,A,S,100
2603,EDM,stack,1,04/03/2015,A,S,100
2603,EDM,stack,1,04/04/2015,A,S,300
2603,EDM,stack,1,04/05/2015,A,S,600
2603,EDM,stack,1,04/06/2015,A,S,50

字段 $1:数字

字段 $2:名称

字段 $3:帐户

字段 $4:发票编号

字段 $5:日期

字段 $6:类型

字段 $7:州

字段 $8:金额

csv 文件中的每一行都需要按 $1 分组,而且字段 $6 中的所有类似字段只有在 NOT C C R 或 A 时才需要加在一起。

预期输出:

2600,AEIOU-2600,C C R,3
2600,AEIOU-2600,C C S,1,10.65
2601,"over, L.P. - 00001",C C S,2,66.43
2601,"over, L.P. - 000001",D C S,1,17.16
2602,UEIA,C C S,5,630
2603,EDM,A,4

正如我们所见,所有类似的类型都被分组、计数并加在一起。唯一的例外是,如果类型是 A 或 C C R,则只计算这些。

字段 $1:数字

字段 $2:名称

字段 $3:类型

字段 $4:类型计数

字段 $5:添加类型

我将不得不使用 gawk,因为一些名称字段包含双引号。

我有这个,但它没有按 $1 和 $6 分组

#!/usr/local/bin/gawk -f

    BEGIN {
    FPAT = "\"[^\"]*\"|[^,]*"

    OFS = ","
    }
    NR > 1 {
        arr[ OFS  OFS  OFS ]++
    }
    END {
        for (key in arr)
            print key, arr[key]
    }

输出:

2600,AEIOU-2600,C C R,1.07,1
2600,AEIOU-2600,C C R,100,1
2600,AEIOU-2600,C C R,200,1
2601,"over, L.P. - 00001",C C S,16.43,1
2601,"over, L.P. - 00001",C C S,50,1
2601,"over, L.P. - 00001",D C S,17.16,1
2602,UEIA,C C S,10,1
2602,UEIA,C C S,30,1
2602,UEIA,C C S,40,1
2602,UEIA,C C S,50,1
2602,UEIA,C C S,500,1
2603,EDM,A,100,2
2603,EDM,A,300,1
2603,EDM,A,50,1
2603,EDM,A,600,1
$ cat tst.awk
BEGIN { FPAT="([^,]*)|(\"[^\"]+\")"; OFS="," }
{
    cnt[][]++
    sum[][]+=$NF
    name[][]=
}
END {
    for (numeric in cnt) {
        for (type in cnt[numeric]) {
            print numeric, name[numeric][type], type, cnt[numeric][type] (type ~ /^(C C R|A)$/? "" : OFS sum[numeric][type])
        }
    }
}

$ awk -f tst.awk file
2600,AEIOU-2600,C C R,3
2600,AEIOU-2600,C C S,1,10.65
2601,"over, L.P. - 00001",D C S,1,17.16
2601,"over, L.P. - 00001",C C S,2,66.43
2602,UEIA,C C S,5,630
2603,EDM,A,5