2012-11-07 89 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