awk分类汇总数据(二维数组)并汇总到新文件

内容:运用bash和awk进行分类统计汇总;
1.测试数据集:
  测试数据格式为: 
  字段分别为ID,Avg,Max,Min,times

1.png
 插入视频
 
2.统计要求:
  (1)不统计times次数大于1;
  (2)不统计Id出现次数小于4;
  (3)统计各ID的Avg,Max,Min的均值,Avg的众数;
  (4)将统计的结果加入对应的ID数据表;
 
3.思路和代码:
  (1)整体思路采用的是分类汇总;
  (2)先筛选出times次数=1的数据,再根据awk的数组计算对数据进行分类统计和分类汇总,最后将ID次数大于3的进行最终计算;
  (3)难点在于awk没有明确意义上的二维数组概念,在版本允许的基础上,可变相采取如下的方式进行计算:

2.png

 
统计实现代码:
#!bin/awk
#calculate.awk
BEGIN{
max=0;print "ID\tFre\tAvg_mean\tMax_mean\tMin_mean\tModFre"
}
{ if($5==1){
Fre[$1]+=1;
Avg[$1]+=$2;
Max[$1]+=$3;
Min[$1]+=$4;
Mode[$1][$2]+=1;
for(id in Mode){
for(num in Mode[id]){
if(Mode[id][num]>max){
max=Mode[id][num]
origin=num
}
}
ModeFre[id]=origin
max=0
origin=0
}
}
}

END{
for(id in Fre){
if(Fre[id]>3){
Avg_mean[id] = int(Avg[id] / Fre[id])
Max_mean[id] = int(Max[id] / Fre[id])
Min_mean[id] = int(Min[id] / Fre[id])
print id "\t" Fre[id] "\t" Avg_mean[id] "\t" Max_mean[id] "\t" Min_mean[id] "\t" ModeFre[id]
}
}
}
统计结果是:

3.png

 

 
  (4)文件汇总根据awk的知识点NF跟FNR的差异进行处理,即在读入多个文件的情况下,NF是持续累计行数,而FNR则是读入当前文件的行数,只要读入下一个文件,则重新计算行数;比如:
读入文件1,文件2,行数都是5,则
NF的行数是:1,2,3,4,5,6,7,8,9,10;
FNR的行数是:1,2,3,4,5;1,2,3,5;
因此可根据NF==FNR判断来分辨文件;
 
   实现代码:
#!bin/awk
#export.awk

{
if(NR==FNR){
Type[$1]=$0;
next
}
if(NR>FNR){
print $0"\t"Type[$1]
}
}
4.最终汇总bash文件
#!bin/bash
#full.sh

jobbase='/home/osboxes/Documents/linux_homework2/'
cat ${jobbase}task.txt|awk -f ${jobbase}calculate.awk > rm2.txt
awk -f ${jobbase}export.awk ${jobbase}rm2.txt ${jobbase}rm.txt
rm rm2.txt



 
 
  

2 个评论

现在发现bash写出来的东西可读性比python差好多。。。 不过好处就是简洁。
而且用dataframe实现,只是一行代码量

要回复文章请先登录注册