计算所有列的平均值,输出中每行的额外信息 bash/awk

Calculating average of all columns, with extra info for each row in the output bash/awk

我的第一个文件(file1.txt):

ID name start end
ID3 pot 15 28
ID2 cat 12 25
ID4 dog 20 30
ID1 turtle 1 10

还有一个文件(file2.txt):

key ID1 ID2 ID3 ID4
23 1.5 2.5 1.2 3.4
5 1.4 2.3 4.2 1.4
21 1.2 2.4 3.5 1.9

输出文件应该是:

name start end field value
turtle 1 10 . 1.37
cat 12 25 . 2.4
pot 15 28 . 6.57
dog 20 30 . 2.23

"name"、"start" 和 "end" 列来自第一个文件。

列"ID"用于linkfile1到file2

计算文件 2 中每个 ID 的平均值,然后将其分配给输出文件中的正确行。例如乌龟有ID1,ID1的平均值为(1.5+1.4+1.2)/3 = 1.37..

并注意输出文件是如何在 "start"

列上排序的

我的 awk 猜测是 ID 将是关联数组中的键

awk '{FNR==NR{a[]=,,;next}' file1.txt

然后对于文件 2,计算类似于 link 描述的列平均值: http://www.fordodone.com/2013/08/02/awk-average-multiple-columns/

cat sample.txt | awk '{for (i=1;i<=NF;i++){a[i]+=$i;}} END {for (i=1;i<=NF;i++){printf "%.0f", a[i]/NR; printf "\t"};printf "\n"}'

但我不太确定如何将它们组合在一起以获得所需的输出。

欢迎任何解决方案,包括 bash 个..

尝试,如果顺序不重要

awk 'FNR==NR{for(i=2;i<=NF;i++){ if(NR==1){ t[i]=$i } else{ A[t[i]]+=$i; c = NR-1 }} next }FNR==1{print "name","start","end","field","value";next}{print ,,,".",A[]/c}' OFMT='%5.2f' OFS='\t'  file2 file1

更好读的版本:

 awk 'FNR==NR{
                for(i=2;i<=NF;i++)
                {
                 if(NR==1)
                 { 
                   t[i]=$i 
                 } 
            else{ 
                   A[t[i]]+=$i
                   c = NR-1 
                }
               } 
                 next 
            }
      FNR==1{
              print "name","start","end","field","value"
              next
            }
            {
              print ,,,".",A[]/c
            }
       '  OFMT='%5.2f' OFS='\t'  file2 file1

输入

 [akshay@localhost tmp]$ cat file1
 ID name start end
 ID3 pot 15 28
 ID2 cat 12 25
 ID4 dog 20 30
 ID1 turtle 1 10

 [akshay@localhost tmp]$ cat file2
 key ID1 ID2 ID3 ID4
 23 1.5 2.5 1.2 3.4
 5 1.4 2.3 4.2 1.4
 21 1.2 2.4 3.5 1.9

输出

 [akshay@localhost tmp]$ awk 'FNR==NR{for(i=2;i<=NF;i++){ if(NR==1){ t[i]=$i } else{ A[t[i]]+=$i; c = NR-1 }} next }FNR==1{print "name","start","end","field","value";next}{print ,,,".",A[]/c}' OFMT='%5.2f' OFS='\t'  file2 file1
 name   start   end field   value
 pot    15      28   .      2.97
 cat    12      25   .      2.40
 dog    20      30   .      2.23
 turtle 1       10   .      1.37