2014-09-26 64 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