awk运行总计数和总和

awk运行总计数和总和,awk,Awk,想知道如何计算供应商每天80%-20%的规则贡献 Input.csv Date,Region,Vendor,Amount 5-Apr-15,east,cc,50 5-Apr-15,east,dd,15 5-Apr-15,south,bb,15 5-Apr-15,south,aa,10 7-Apr-15,east,cc,123 7-Apr-15,south,bb,88 7-Apr-15,south,aa,40 7-Apr-15,west,ss,30 7-Apr-15,west,rr,20 在上述

想知道如何计算供应商每天80%-20%的规则贡献

Input.csv

Date,Region,Vendor,Amount
5-Apr-15,east,cc,50
5-Apr-15,east,dd,15
5-Apr-15,south,bb,15
5-Apr-15,south,aa,10
7-Apr-15,east,cc,123
7-Apr-15,south,bb,88
7-Apr-15,south,aa,40
7-Apr-15,west,ss,30
7-Apr-15,west,rr,20
在上述输入中,基于$1字段需要填充金额的运行总和,然后计算当天金额的运行总和百分比

Date,Region,Vendor,Amount,RunningSum,%RunningSum
5-Apr-15,east,cc,50,50,56%   (RunningSum=50 , %RunningSum=50/90(Total Amount for the day) 
5-Apr-15,east,dd,15,65,72%   (RunningSum=50+15, %RunningSum=65/90)
5-Apr-15,south,bb,15,80,89%  (RunningSum=65+15, %RunningSum=80/90)
5-Apr-15,south,aa,10,90,100% (RunningSum=80+10, %RunningSum=90/90)

一旦得到80%或80%以上的第一次击中需要考虑作为80%的贡献剩余的行项目需要考虑为20%的贡献。 预期产出:

Date,Countof80%Vendor, SumOf80%Vendor, Countof20%Vendor, SumOf20%Vendor
5-Apr-15,3,80,1,10
7-Apr-15,3,251,2,50

任何建议…

在awk中执行此操作相对比较复杂,但现在开始

awk -F , '{vals[$1,++nums[$1]]=$4}END{
    for(d in nums){
        tot=0
        for(i=1;i<=nums[d];i++)tot+=vals[d,i]
        n=0;s=0
        for(i=1;i<=nums[d];i++){
            n++;s+=vals[d,i]
            if(s>=tot*0.8){s80=s;n80=n;s=0;n=0}
        }
        printf("%s,%d,%d,%d,%d\n",d,n80,s80,n,s)
    }
}' vendors.txt
这将为每个日期创建独立的值列表,并在通过这些列表收集所有数据循环并计算出80%点的位置之后

这假设文件只包含数据,没有日期、地区、供应商。。标题。如果要复制和粘贴一行版本,请参见:

awk -F , '{vals[$1,++nums[$1]]=$4}END{for(d in nums){tot=0;for(i=1;i<=nums[d];i++)tot+=vals[d,i];n=0;s=0;for(i=1;i<=nums[d];i++){n++;s+=vals[d,i];if(s>=tot*0.8){s80=s;n80=n;s=0;n=0}};printf("%s,%d,%d,%d,%d\n",d,n80,s80,n,s)}}' vendors.txt
编辑:如果要对每个区域分别计数,只需将$1部分更改为$1,$2,以连接日期和区域:

awk -F , '{a=$1","$2;vals[a,++nums[a]]=$4}END{for(d in nums){tot=0;for(i=1;i<=nums[d];i++)tot+=vals[d,i];n=0;s=0;for(i=1;i<=nums[d];i++){n++;s+=vals[d,i];if(s>=tot*0.8){s80=s;n80=n;s=0;n=0}};printf("%s,%d,%d,%d,%d\n",d,n80,s80,n,s)}}' vendors.txt
不过,老实说,我有点不清楚你到底想用这个来衡量什么。例如,占销售额80%的供应商数量并不是唯一定义的,这取决于您对其进行排序的顺序。如果你先对所有的小销售额进行排序,你会得到一个比你先对大销售额排序更大的数字。如果你不按特定的顺序对它们进行排序,你会得到一些中间的东西。如果您想知道有多少最大的供应商占销售额的80%,那么您需要在计算之前对阵列进行排序

$ cat tst.awk
BEGIN { FS=OFS="," }
NR==FNR { tot[$1] += $NF; next }
FNR==1 { print $0, "RunningSum", "%RunningSum"; next }
{ sum[$1]+=$NF; print $0, sum[$1], int(0.5+sum[$1]*100/tot[$1])"%" }

$ awk -f tst.awk file file
Date,Region,Vendor,Amount,RunningSum,%RunningSum
5-Apr-15,east,cc,50,50,56%
5-Apr-15,east,dd,15,65,72%
5-Apr-15,south,bb,15,80,89%
5-Apr-15,south,aa,10,90,100%
7-Apr-15,east,cc,123,123,41%
7-Apr-15,south,bb,88,211,70%
7-Apr-15,south,aa,40,251,83%
7-Apr-15,west,ss,30,281,93%
7-Apr-15,west,rr,20,301,100%

我已经为你问题的第一部分提供了上面的答案,但我不知道从80%推导出来的部分与它有什么关系。对于相同的输入,您是否希望输出到单独的文件中?附加到上述输出中?不同的剧本?还有别的吗

这里有一个awk脚本,可以在日期更改时执行此操作:

#!/usr/bin/awk -f

BEGIN {
    FS=OFS=","
    print "Date" OFS "Countof80%Vendor" OFS "SumOf80%Vendor" OFS "Countof20%Vendor" OFS "SumOf20%Vendor"
}

FNR==1 { next } # skip the header

last_1 != $1 && FNR > 2 {
    output( a, cnt, tot, last_1 )
    cnt = tot = 0
    delete( a )
}

{ tot += $4; a[++cnt] = tot; last_1 = $1 }

END { output( a, cnt, tot, last_1 ) }


func output( a, cnt, tot, last_date,                 perc80, i, runsum ) {
    perc80 = .8 * tot
    for(i=1; i<=cnt; i++) {
        runsum = a[i]
        if(runsum >= perc80) {
            print last_date OFS i OFS runsum OFS (cnt-i) OFS (tot-runsum)
            break
        }
    }
}

Ed Morton,感谢您的输入,实际上我想检查有多少供应商贡献了80%的业务,或者直到第一次达到80%以上,以及基于金额字段$4的20%的业务。问题的第一部分解释了我是如何计算80%-20%规则的。是的,如果相同的输入没有附加到上述输出中,您是否希望将例外输出到单独的文件中?您是否真的希望两个表都输出?或者您是否只希望最终表输出?Ed Morton,只希望最终表输出Tanks a ton-n0741337非常好的解释,如果我需要区分日期$1和区域$2,在哪里更改代码:80%-20%规则,如输出标题日期、区域、80%供应商的计数、80%供应商的计数、20%供应商的计数、20%供应商的计数。如果我理解正确,只要文件按$1和$2排序,您只需更改最后一个_1的测试和制作方式。例如,last_1!=$2美元中的1美元。输出中的last_date可以重命名为last_date_region,并且应该在标题中添加一个额外的列。感谢大量的输入,如果需要将日期$1和区域$2分开,可以在哪里更改代码:80%-20%规则,如输出标题日期、区域、80%供应商的计数、80%供应商的计数、20%供应商的计数、20%供应商的计数或区域,我试图按日期和地区衡量占销售额80%的最大供应商,因此,在运行脚本之前,我将根据日期和地区对输入详细信息进行排序,从最高到最低,这样我就可以看到每个日期和地区级别有多少供应商贡献了80%的销售额
Date,Countof80%Vendor,SumOf80%Vendor,Countof20%Vendor,SumOf20%Vendor
5-Apr-15,3,80,1,10
7-Apr-15,3,251,2,50