2016-12-17 35 views
0

任何人都可以告訴我如何使用awk來計算使用數據集的唯一標識($ 1)和測量($ 3)記錄的每一天($ 2)重複記錄的平均值。 數據集看起來如下:如何使用awk計算一天內重複記錄的平均值?

32070  2010-12-15 540 
32070  2010-12-15 546 
32070  2010-12-15 549 
32070  2010-12-17 579 
32070  2010-12-17 553 
25903  2010-12-15 556 
25903  2010-12-15 543 
25903  2010-12-15 564 
25903  2010-12-16 567 
25903  2010-12-16 583 

我想有基於每一個唯一的ID($ 1)測量($ 3)每天記錄($ 2)的平均值,並分別打印我的文件輸出到容貌像如下:

32070 2010-12-15 545 
32070 2010-12-17 566 
25903 2010-12-15  554.33 
25903 2010-12-16  575 

回答

2
$ cat tst.awk 
{ curr = $1 OFS $2 } 
curr != prev { if (cnt) print prev, sum/cnt; sum=cnt=0 } 
{ sum+=$3; cnt++; prev=curr } 
END { if (cnt) print prev, sum/cnt } 

$ awk -f tst.awk file 
32070 2010-12-15 545 
32070 2010-12-17 566 
25903 2010-12-15 554.333 
25903 2010-12-16 575 

這個和@Ruslans回答之間的不同之處在於:

  1. 他在存儲器中存儲整個輸入文件,同時在上述剛存儲了4個變量(CURR,分組,和的值,和cnt)在內存中。
  2. 他輸出的結果是隨機的(實際上是大多數awk實現中的哈希)順序,而上面的輸出結果按照它們出現在輸入中的順序輸出。
  3. 無論您的輸入發生在什麼順序,他的工作都會起作用,而上面的工作依賴於按ID和日期排序的輸入。
+1

@埃德莫頓謝謝 – Alula

+0

劇本只是給我,因爲它與平均每日記錄。我期待着你的迴應。謝謝 – Alula

+0

你複製/粘貼它時做錯了什麼,或者你的輸入不像你提供的樣本。正如你可以在我的回答中看到的那樣,腳本根據你提供的示例輸入做你要求的內容。 –

0
BEGIN { SUBSEP = "@" } 

{ a[$1,$2] += $3; n[$1,$2]++ } 

END { 
    for (x in a) { 
    split(x, parts, SUBSEP) 
    print parts[1] " " parts[2] " " a[x]/n[x] 
    } 
} 

輸出

25903 2010-12-15 554.333 
25903 2010-12-16 575 
32070 2010-12-15 545 
32070 2010-12-17 566 

說明

SUBSEP是在multidimensional arrays用於單獨的鍵的內部變量。它的默認值是"\034",這不太可能出現在輸入中。我已將其設置爲@進行調試。你可以跳過修改這個變量。

與「預期輸出」相比,輸出將採用不同的順序。但是您可以使用sort工具按列分類。例如,下面將排序的第二列中的輸出,然後由所述第一柱(按該順序):

awk -f script.awk file | sort -k2 -k1g 

輸出

25903 2010-12-15 554.333 
25903 2010-12-16 575 
32070 2010-12-15 545 
32070 2010-12-17 566 

這僅僅是一個示例。你應該有個大概的想法。根據您的需要修改命令。

+0

謝謝。有用。 – Alula

+0

如果您想將SUBSEP設置爲某項,請將其設置爲OFS,然後您不需要在END部分中使用「split()」和「parts」數組,只需按原樣打印「x」索引同時擺脫硬編碼的''''支持正常的','輸出分隔符。 –

+1

@EdMorton,謝謝。我只是想向他展示大致的想法。我覺得你的建議很有用,我認爲OP也會發現它們很有用。 –