awk分类汇总数据(二维数组)并汇总到新文件
内容:运用bash和awk进行分类统计汇总;
1.测试数据集:
测试数据格式为:
字段分别为ID,Avg,Max,Min,times
插入视频
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没有明确意义上的二维数组概念,在版本允许的基础上,可变相采取如下的方式进行计算:
统计实现代码:
(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判断来分辨文件;
实现代码:
1.测试数据集:
测试数据格式为:
字段分别为ID,Avg,Max,Min,times
插入视频
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没有明确意义上的二维数组概念,在版本允许的基础上,可变相采取如下的方式进行计算:
统计实现代码:
#!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]
}
}
}
(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/awk4.最终汇总bash文件
#export.awk
{
if(NR==FNR){
Type[$1]=$0;
next
}
if(NR>FNR){
print $0"\t"Type[$1]
}
}
#!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