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

Csv 使用awk对数据进行分组和计算,csv,awk,gawk,bsd,Csv,Awk,Gawk,Bsd,我想使用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. - 0

我想使用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中的所有类似字段也需要添加在一起,只有当它们是而不是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 R,则只计算它们

字段$1:数字

字段$2:名称

字段$3:类型

字段$4:类型的计数

字段$5:添加类型

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

我有这个,但不是按1美元和6美元分组

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

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

    OFS = ","
    }
    NR > 1 {
        arr[$1 OFS $2 OFS $6 OFS $8]++
    }
    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

嗨,艾德,好的,我会的。嗯,这基本上是一个复制品。(我知道Ed建议问一个新问题,我不会这么做的)。另一方面,它过于本地化。过于本地化意味着问题本身+可能的答案通常只对你感兴趣。在这种情况下,这将是一个滥用这个网站,因为我们不是一个代码编写服务。我想你是在这个行业工作,所以你得到了这个问题的结果。我们为什么要做这项工作呢?嗨,hek2mgl,我认为这对其他人来说可能很有趣,因为它询问如何通过多个列进行分组,并将一些数据汇总在一起。“我并没有为此得到报酬,但我明白如果我滥用了SO及其出色的贡献者,”RegisteredUser只是另一个提示。如果你的问题只是一般的分组问题,请注意回答这类问题的人非常喜欢包含
foo,bar,hello,world,1,2,3
中单词的例子,而类似
AEIOU-2600,C C R,1.07
的例子就糟透了。。如果你想让别人对这个问题更感兴趣,我鼓励你用这种方式简化你的问题。但是要小心!不要简化不能简化的内容,也就是说不要删除重要信息。@hek2mgl问题是OP遵循了我给出的一条建议,发布了一个新问题,但没有遵循另一条建议,即将他以前的问题恢复到开始的方式。如果他这样做了,你不会觉得你一天看同一个问题两次,因为上一个问题本来就很不一样。嗨,艾德,好吧,我会的。嗯,这(不止)基本上是重复的。(我知道Ed建议问一个新问题,我不会这么做的)。另一方面,它过于本地化。过于本地化意味着问题本身+可能的答案通常只对你感兴趣。在这种情况下,这将是一个滥用这个网站,因为我们不是一个代码编写服务。我想你是在这个行业工作,所以你得到了这个问题的结果。我们为什么要做这项工作呢?嗨,hek2mgl,我认为这对其他人来说可能很有趣,因为它询问如何通过多个列进行分组,并将一些数据汇总在一起。“我并没有为此得到报酬,但我明白如果我滥用了SO及其出色的贡献者,”RegisteredUser只是另一个提示。如果你的问题只是一般的分组问题,请注意回答这类问题的人非常喜欢包含
foo,bar,hello,world,1,2,3
中单词的例子,而类似
AEIOU-2600,C C R,1.07
的例子就糟透了。。如果你想让别人对这个问题更感兴趣,我鼓励你用这种方式简化你的问题。但是要小心!不要简化不能简化的内容,也就是说不要删除重要信息。@hek2mgl问题是OP遵循了我给出的一条建议,发布了一个新问题,但没有遵循另一条建议,即将他以前的问题恢复到开始的方式。如果他这样做了,你不会觉得你一天看同一个问题两次,因为上一个问题本来就很不一样。嗨,艾德,好吧,我会的。嗯,这(不止)基本上是重复的。(我知道Ed建议问一个新问题,我不会这么做的)。另一方面,它过于本地化。过于本地化意味着问题本身+可能的答案通常只对你感兴趣。在这种情况下,这将是一个滥用这个网站,因为我们不是一个代码编写服务。我想你是在这个行业工作,所以你得到了这个问题的结果。我们为什么要做这项工作呢?嗨,hek2mgl,我认为这对其他人来说可能很有趣,因为它询问如何通过多个列进行分组,并将一些数据汇总在一起。“我并没有为此得到报酬,但我明白如果我滥用了SO及其出色的贡献者,”RegisteredUser只是另一个提示。如果你的问题只是一般的分组问题,请注意回答这类问题的人非常喜欢包含
foo,bar,hello,world,1,2,3
中单词的例子,而类似
AEIOU-2600,C C R,1.07
的例子就糟透了。。如果你想让别人对这个问题更感兴趣,我鼓励你用这种方式简化你的问题。但是要小心!不要简化不能简化的内容,也就是说不要删除重要信息。@hek2mgl问题是OP遵循了我给出的一条建议,发布了一个新问题,但没有遵循另一条建议,即将他以前的问题恢复到开始的方式。如果他这样做了,你不会觉得你一天看同一个问题两次,因为上一个问题本来就很不一样。嗨,艾德,好吧,我会的。嗯,这(不止)基本上是重复的。(我知道Ed建议问一个新问题,我不会这么做的)。另一方面,它过于本地化。过于本地化意味着问题本身+可能的答案通常只对你感兴趣。如果是那样的话
$ cat tst.awk
BEGIN { FPAT="([^,]*)|(\"[^\"]+\")"; OFS="," }
{
    cnt[$1][$6]++
    sum[$1][$6]+=$NF
    name[$1][$6]=$2
}
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