2012-11-07 128 views
7

我有500个文件,名称为fort.1,fort.2 ... fort.500。每个文件包含如下800个数据:使用awk从多个文件计算平均值

1 0.485
2 0.028
3 0.100
4 0.979
5 0.338
6 0.891
7 0.415
8 0.368
9 0.245
10 0.489

我想从每个文件中获得每行第二列的平均值。换句话说,从所有文件中获得第二列第一行的平均值并存储在“output.file”中。然后获得第二行第二列的平均值并存储在相同的“output.file”中。 我试着用粘贴命令,但没有得到我想要的。 AWK有什么办法吗?

感谢任何帮助。 感谢

回答

1

我的理解:每个文件是在特定位置的一组度量。您想要汇总所有位置的测量值,将每个文件中同一行的值平均到新文件中。

假设第一列可以作为行的ID进行处理(也有在一个文件800次测量):

cat fort.* | awk ' 
BEGIN { 
    for (i = 1; i <= 800; i++) 
     total[i] = 0 
} 

{ total[$1] += $2 } 

END { 
    for (i = 1; i <= 800; i++) 
     print i, total[i]/500 
} 
' 

首先,我们初始化一个数组来存储的总和为在所有的行文件。

然后,我们循环连接起来的文件。我们使用第一列作为行的关键字,然后我们将数组加入。

最后,我们循环阵列上方,并通过排在所有文件打印的平均值。

+0

在这段代码我的理解是,在首先要从值fort.1文件保持在“全部”数组中。接下来读取第二个文件fort.2并保持数组。 (例如),那么它应该分别从第一个和第二个文件(总数[1] +总数[1]/2)中获得平均值。但我没有得到这个......对不起,如果我理解不正确。 – Vijay

+0

编辑以反映我对问题的假设。 –

+0

感谢您的快速回复。让我再次澄清我想要的。每个文件(共500个文件)包含两列(第一列和第二列)和800行的行。我想要添加每个文件(所有500个文件)的第一行,第二列并计算平均值,并将其作为average.output存储在新文件中。然后进入所有文件(500个文件)的第二行,第二列并计算average.output的平均值和存储。直到average.output文件包含800行。希望你得到这个解释。对不起,如果我在帖子中的问题困惑你。先谢谢你。 – Vijay

2

假设第一列是ID:

cat fort.* | awk '{sum[$1] += $2; counts[$1]++;} END {for (i in sum) print i, sum[i]/counts[i];}' 
5

下面是使用pasteawk的快捷方式:

paste fort.* | awk '{ for(i=2;i<=NF;i+=2) array[$1]+=$i; if (i = NF) print $1, array[$1]/NF*2 }' > output.file 

像一些其他的答案;还有一种方法,但是这一次使用sort获得数字顺序排序输出:

awk '{ sum[$1]+=$2; cnt[$1]++ } END { for (i in sum) print i, sum[i]/cnt[i] | "sort -n" }' fort.* 
7

AWK不上第一列任何假设:

awk '{a[FNR]+=$2;b[FNR]++;}END{for(i=1;i<=FNR;i++)print i,a[i]/b[i];}' fort.* 
+0

这段代码是否考虑所有的“所有输入文件的第一行(fort.1,fort.2 ...)”并计算出平均值,然后进入所有文件的第二行(fort.1,fort.2 ... ),直到每个文件800行?我需要一些解释来理解这段代码实际上做了什么。谢谢 – Vijay

+0

@Vijay:它的确确实实在......更新了堡垒。*使之更加清晰。你可以测试一个小样本文件来确认... – Guru

+0

大师,这段代码工作正常。谢谢。另外还需要添加小东西。我有名称为fort.1,fort.2等的文件。我害怕如果我把堡垒*,它会读堡垒1,堡垒10,堡垒100,而不是堡垒1,堡垒2等等。这可以如何处理?谢谢 – Vijay