2011-08-07 76 views
0

这是我的输入文件的样本:awk的柱的平均部分,如果线(特定字段)匹配

$cat NDVI-bm 
P01 031.RAW 0.516 0 0 
P01 021.RAW 0.449 0 0 
P02 045.RAW 0.418 0 0 
P03 062.RAW 0.570 0 0 
P03 064.RAW 0.469 0 0 
P04 083.RAW 0.636 0 0 
P04 081.RAW 0.592 0 0 
P04 082.RAW 0.605 0 0 
P04 084.RAW 0.648 0 0 
P05 093.RAW 0.748 0 0 

如果第一字段匹配我需要平均柱3。很简单,但我挣扎的我的awk知识是很基础...这是我到目前为止有:

awk '{array[$1]+=$3(need to divide here by number of matches...)} END { for (i in array) {print i"," array[i]}}' NDVI-bm 

在网上搜索,我真的不知道我在标题中正确的方式...除非有一个简单的方法来计算匹配的数量,至少我不能找到...任何想法?

感谢您的帮助!

回答

4

例如,计算开始 “P01” 线的平均:

/^P01/{ 
    num+=1 
    cnt+=$3 
} 
END {print "avg = " cnt/num} 

输出:

$ awk -f avg.awk input 
avg = 0.4825 

...或者,作为oneliner:

$ awk '/^P01/{cnt+=$3; num+=1} END{print "avg="cnt/num}' input 

或者对第一列的所有数值同时进行计算:

{ 
    sum[$1]+=$3 
    cnt[$1]++ 
} 


END { 
    print "Name" "\t" "sum" "\t" "cnt" "\t" "avg" 
    for (i in sum) 
     print i "\t" sum[i] "\t" cnt[i] "\t" sum[i]/cnt[i] 

} 

输出:

$ awk -f avg.awk input 
Name sum  cnt  avg 
P01  0.965 2  0.4825 
P02  0.418 1  0.418 
P03  1.039 2  0.5195 
P04  2.481 4  0.62025 
P05  0.748 1  0.748 
+0

感谢您的回答弗雷德里克,但我的文件是相当大的......我不能计算出平均一个接一个。 – Chargaff

+0

查看更新回答:-) –

+0

嘿,这是一个非常简单和优雅的解决方案...我正在寻找一种复杂的方式...我正在学习!再次感谢 ! – Chargaff

0

有一个不同的数组,您可以跟踪每个索引所见的条目数,并在END块中执行除法。

1
{ total[$1] += $3; ++n[$1] } 

END { for(i in total) print i, total[i]/n[i] } 
相关问题