使用awk,根据第2列和第5列中的字符串以及第3列中的值计算行的平均值,并追加结果

使用awk,根据第2列和第5列中的字符串以及第3列中的值计算行的平均值,并追加结果,awk,pattern-matching,average,calculated-columns,Awk,Pattern Matching,Average,Calculated Columns,这是上的一个变体 输入数据.txt: a;2016-04-25;10;2016-w17;2016-q2 b;2016-04-25;20;2016-w17;2016-q2 c;2016-04-25;30;2016-w17;2016-q2 d;2016-04-26;40;2016-w17;2016-q2 e;2016-07-25;50;2016-w30;2016-q3 f;2016-07-25;60;2016-w30;2016-q3 g;2016-07-25;70;2016-w30;2016-q3

这是上的一个变体

输入数据.txt:

a;2016-04-25;10;2016-w17;2016-q2
b;2016-04-25;20;2016-w17;2016-q2
c;2016-04-25;30;2016-w17;2016-q2
d;2016-04-26;40;2016-w17;2016-q2
e;2016-07-25;50;2016-w30;2016-q3
f;2016-07-25;60;2016-w30;2016-q3
g;2016-07-25;70;2016-w30;2016-q3
想要的输出.txt:

a;2016-04-25;10;2016-w17;2016-q2;50
b;2016-04-25;20;2016-w17;2016-q2;50
c;2016-04-25;30;2016-w17;2016-q2;50
d;2016-04-26;40;2016-w17;2016-q2;50
e;2016-07-25;50;2016-w30;2016-q3;180
f;2016-07-25;60;2016-w30;2016-q3;180
g;2016-07-25;70;2016-w30;2016-q3;180
因此,计算有数据的天数的季度平均数并附加结果

2016年第二季度的平均值计算如下:

(10+20+30+40)/2 = 50     ("2" is the number_of_unique_dates for that quarter)
2016-3季度的平均值为:

(50+60+70)/1 = 180
这是我正在进行的工作,似乎很接近最终解决方案, 但不确定如何获取“唯一日期数”(第2列) 并用作除数

awk '
BEGIN { FS=OFS=";" }
NR==FNR { s[$5]+=$3; next }
{ print $0,s[$5] / need_num_of_unique_dates_here }
 ' output.txt output.txt 
知道如何获得每个季度的“唯一日期数”吗?

$cat tst.awk
$ cat tst.awk
BEGIN { FS=OFS=";" }
$5 != p5 { prt(); p5=$5 }
{ lines[++numLines]=$0; dates[$2]; sum+=$3 }
END { prt() }
function prt(   lineNr) {
    for (lineNr=1; lineNr<=numLines; lineNr++) {
        print lines[lineNr], sum/length(dates)
    }
    delete dates
    numLines = sum = 0
}

$ awk -f tst.awk file
a;2016-04-25;10;2016-w17;2016-q2;50
b;2016-04-25;20;2016-w17;2016-q2;50
c;2016-04-25;30;2016-w17;2016-q2;50
d;2016-04-26;40;2016-w17;2016-q2;50
e;2016-07-25;50;2016-w30;2016-q3;125
f;2016-07-25;60;2016-w30;2016-q3;125
g;2016-07-25;70;2016-w30;2016-q3;125
h;2016-04-01;70;2016-w30;2016-q3;125
开始{FS=OFS=“;”} $5 != p5{prt();p5=$5} {行[++numLines]=$0;日期[$2];总和+=$3} 结束{prt()} 功能prt(线路编号){ 对于(lineNr=1;lineNr
$cat tst.awk
开始{FS=OFS=“;”}
$5!=p5{prt();p5=$5}
{行[++numLines]=$0;日期[$2];总和+=$3}
结束{prt()}
功能prt(线路编号){
对于(lineNr=1;lineNr另一个gawk解决方案:

awk -F';' '{ a[$5][$2]+=$3; r[NR]=$0; q[NR]=$5 }
     END { 
           for (i in a) { s=0; len=length(a[i]); 
               for (j in a[i]) { s += a[i][j] } 
               a[i]["avg"] = s/len 
           } 
           for (n=1;n<=NR;n++) { print r[n],a[q[n]]["avg"] }
     }' OFS=";" file

  • 一个[$5][$2]+=$3
    多维数组,对某个季度内每个唯一日期的值求和

  • len=length(a[i])
    -确定某个季度内唯一日期的数量

  • 对于(a[i]中的j]){s+=a[i][j}
    -对四分之一内所有日期的值求和

  • a[i][“avg”]=s/len
    -计算平均值

另一个呆呆的解决方案:

awk -F';' '{ a[$5][$2]+=$3; r[NR]=$0; q[NR]=$5 }
     END { 
           for (i in a) { s=0; len=length(a[i]); 
               for (j in a[i]) { s += a[i][j] } 
               a[i]["avg"] = s/len 
           } 
           for (n=1;n<=NR;n++) { print r[n],a[q[n]]["avg"] }
     }' OFS=";" file

  • 一个[$5][$2]+=$3
    多维数组,对某个季度内每个唯一日期的值求和

  • len=length(a[i])
    -确定某个季度内唯一日期的数量

  • 对于(a[i]中的j]){s+=a[i][j}
    -对四分之一内所有日期的值求和

  • a[i][“avg”]=s/len
    -计算平均值


@EdMorton感谢您指出这一点!将模式替换为字符串。我从上一个问题中的输入开始,但问题变得冗长,因此为了使其紧凑,我选择了上面的数据。。是的,我完全同意!@EdMorton感谢您指出这一点!将模式替换为字符串。我从上一个问题中的输入开始但是问题变得冗长了,所以为了使其紧凑,我选择了上面的数据。。是的,我完全同意!感谢您的解决方案,由于某种原因,我的输出中的行的输出顺序发生了更改?我使用GNU Awk 4.0.1.d,e,f,f,g,a,b,c而不是a,b,c,d,e,f,g。但是行看起来是正确的。@Markus,好的,明白了。解决了一个小问题OFS设置为,并且可以更改为;@Markus,是的,偶尔会错过这个,修正解决方案,由于某种原因,在我的输出中行的输出顺序发生了变化?我使用GNU Awk 4.0.1.d,e,f,g,a,b,c而不是a,b,c,d,e,f,g。但是行看起来是正确的。@Markus,好的,明白了。修正了OFS设置为的一个小东西,可以是cha我想;@Markus,是的,偶尔会错过,修正了