使用AWK在日志中查找缺少的日期

时间:2014-09-26 02:08:12

标签: awk

我正在尝试在日志文件中找到缺少的日期。基本上,我有2个输入文件,一个'eventlist'和一个'eventlog',如下所示:

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 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

Awk to calculate number of days between two dates的回答建议的另一种方法是(假设为了简单起见,EV01文件中的Event number oneeventlist之间有一个标签:

#!/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将一个充满日期的文件转换为自纪元以来的秒数,因此我们可以将该数字除以一天中的秒数(86400)以查找自此以来的天数时代。找到每个事件的最近连续天数是很简单的,我们可以使用join(使用选项卡作为字段分隔符)和cut的组合将较长的标签与每个事件计数进行匹配。

此解决方案使用的工具多于@glenn jackman的解决方案,但不需要mktime()strftime()awk的所有方言都可能无法使用这些工具。