Linux 具有不同行大小的多个文件的平均值

Linux 具有不同行大小的多个文件的平均值,linux,shell,awk,average,Linux,Shell,Awk,Average,我有几个行大小不同的文件,但每个文件中的列数是相同的。e、 g ifile1.txt 1 1001 ? ? 2 1002 ? ? 3 1003 ? ? 4 1004 ? ? 5 1005 ? 0 6 1006 ? 1 7 1007 ? 3 8 1008 5 4

我有几个行大小不同的文件,但每个文件中的列数是相同的。e、 g

ifile1.txt

1       1001    ?       ?
2       1002    ?       ?
3       1003    ?       ?
4       1004    ?       ?
5       1005    ?       0
6       1006    ?       1
7       1007    ?       3
8       1008    5       4
9       1009    3       11
10      1010    2       9
ifile2.txt

1       2001    ?       ?
2       2002    ?       ?
3       2003    ?       ?
4       2004    ?       ?
5       2005    ?       0
6       2006    6       12
7       2007    6       5
8       2008    9       10
9       2009    3       12
10      2010    5       7
11      2011    2       ?
12      2012    9       ?
ifile3.txt

1       3001    ?       ?
2       3002    ?       6
3       3003    ?       ?
4       3004    ?       ?
5       3005    ?       0
6       3006    1       25
7       3007    2       3
8       3008    ?       ?
在每个文件中,第一列表示索引号,第二列表示ID。 我想从第三列开始计算每个索引编号的平均值

所需输出:

1       ?       ?      ----  [Here ? is computed from ?, ?, ?] So answer is ?
2       ?       6.0    ----  [Here 6 is computed from ?, ?, 6] So answer is 6/1=6.0
3       ?       ?
4       ?       ?
5       ?       0.0
6       3.5     12.7 
7       4.0     3.7
8       7.0     7.0    ----- [Here 7 is computed from 5, 9, ? ] So answer is 14/2=7.0   
9       3.0     11.5
10      3.5     8.0
11      2.0     ?
12      9.0     ?

您可以解析文件并将每个位置的总和和计数存储在某种二维数组中,这种数组对于awk来说并不存在,但可以使用适当的索引字符串来实现,另请参见:

下面是一个使用示例输入和输出测试的脚本

{
    c = NF
    if (r<FNR) r = FNR
    
    for (i=3;i<=NF;i++) {
        if ($i != "?") {
            s[FNR "," i] += $i
            n[FNR "," i] += 1
        }
    }
}

END {
    for (i=1;i<=r;i++) {
        printf("%s\t", i)
        for (j=3;j<=c;j++) {
            if (n[i "," j]) {
                printf("%.1f\t", s[i "," j]/n[i "," j])
            } else {
                printf("?\t")
            }
        }
        printf("\n")
    }
}
但是它把所有的“?”都取为0。
所以检查它。如果
s[i]
中的所有元素都等于
,则输出一个
。即
所有问题=1;对于(s中的i)如果(s[i]!=“?”)所有问题=0
则稍后如果(所有问题)打印“”,否则打印如果c[i]>0,则某些行不是“”<代码>awk'{n[$1]+}$3=“?”{s[$1]+=$3;c[$1]+;}END{for(i in n)print i,(c[i]?sprintf(“%.1f”,s[i]/c[i]):“?”;}'ifile*
> awk -f test.awk file1 file2 file3
1       ?       ?
2       ?       6.0  
3       ?       ?
4       ?       ?
5       ?       0.0
6       3.5     12.7
7       4.0     3.7
8       7.0     7.0
9       3.0     11.5
10      3.5     8.0
11      2.0     ?
12      9.0     ?