2014-09-26 63 views
1

我正在嘗試在日誌文件中查找缺失的日期。從本質上講,我有2個輸入文件,一個「事件列表」和「事件日誌」看起來像這樣:使用AWK查找日誌中的缺失日期

eventlist 
EV01 Event number one 
EV02 Event number two 

eventlog 
2014-09-14 EV01 
2014-09-16 EV01 
2014-09-20 EV01 
2014-09-21 EV01 
2014-09-22 EV01 
2014-09-23 EV01 
2014-09-24 EV01 
2014-09-25 EV01 
2014-09-14 EV02 
2014-09-22 EV02 
2014-09-23 EV02 
2014-09-24 EV02 
2014-09-25 EV02 

我想看到的連續天數(從今天),我有事件日誌記錄。根據上述文件,我想下面的輸出:

6 Event number one 
4 Event number two 

到目前爲止,我有下面的腳本,但它返回我爲每個事件發生計數:

awk 'NR==FNR { a[$1]=$0; next }{print $1,a[$2]}' eventlist eventlog | awk '{print substr($0, index($0, $3))}' | awk -F, '!z[$1]++{ a[$1]=$0; } END {for (i in a) print z[i], a[i]}' 

目前這回報:

8 Event number one 
5 Event number two 

我如何能修改上面給我的連續天數(到今天爲止),而不是總數任何想法?

回答

2

我喜歡這樣的挑戰。這裏遲到了:明天要求解釋。

gawk ' 
    BEGIN { today = strftime("%F", systime()) } 
    function day_before(date) { 
     gsub(/-/, " ", date) 
     return strftime("%F", mktime(date " 12 00 00") - 86400) 
    } 
    NR == FNR { id = $1; $1 = ""; event[id] = $0; next } 
    $NF != eid { day = today; eid = $NF } 
    $1 > today { next } 
    $1 == day { count[eid]++; day = day_before(day) } 
    END { for (id in count) print count[id], event[id] } 
' eventlist <(tac eventlog) 
6 Event number one 
4 Event number two 
+0

嗨格倫 - 謝謝你的答案。這很好。你介意走這個,所以我可以關注?我已經接受了解決方案,只是想確保我理解它的工作原理。 – armohan 2014-09-26 10:47:05

+0

我不介意,但首先有沒有**你不明白的**部分? – 2014-09-26 10:56:05

+0

特別是函數後面的2行:NR == FNR {id = $ 1; $ 1 =「」;事件[id] = $ 0;下一個} $ NF!= eid {day = today; eid = $ NF} – armohan 2014-09-26 12:31:57

1

一種替代方案中,通過回答Awk to calculate number of days between two dates建議,將(假設爲簡單起見,有在eventlist文件EV01Event number one之間的選項卡):

#!/bin/sh 
cut -f2 -d" " eventlog >ev.tmp 
cut -f1 -d" " eventlog | date -f - +%s | awk '{print int($0/86400)}' \ 
    | paste - ev.tmp | awk '{if (lastDay[$2] == $1-1) consecCount[$2]++; 
else consecCount[$2]=1; lastDay[$2] = $1} 
    END {for (i in consecCount) print i "\t" consecCount[i]}' \ 
     | sort | join -t" " - eventlist | cut -f2,3 

這裏的關鍵步驟是,date -f將一個文件充滿日期轉換爲自紀元以來的秒數,所以我們可以將該數字除以秒數ds在一天(86400)中查找自該時代以來的天數。查找每個事件的最近連續日數是很簡單的,我們可以使用join(使用製表符作爲字段分隔符)和cut將較長的標籤與每個事件計數進行匹配。

該解決方案使用的工具多於@glenn jackman的解決方案,但是不需要mktime()strftime(),這可能不適用於所有awk方言。

+0

西蒙,我試過這個,'連接'部分似乎沒有工作。我得到一個錯誤,說「加入:多字符標籤」'「。我嘗試修改'join -t'旁邊的空格並運行腳本,但是我沒有看到任何輸出? – armohan 2014-09-26 10:52:51

+0

@armohan:說服'join'使用製表符作爲分隔符是非常棘手的,但在雙引號之間按下鍵對我很有幫助。或者,您可以使用擊鍵或者您可以使用問題答案中顯示的其他技術[Unix join separator char](http://stackoverflow.com/questions/1722353/unix-join-separator-char)。 – Simon 2014-09-27 03:20:25