使用AWK查找日志中缺少的日期
我试图在日志文件中查找丢失的日期。基本上,我有两个输入文件,“事件列表”和“事件日志”,如下所示:使用AWK查找日志中缺少的日期,awk,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-
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
关于如何修改上述内容以显示连续天数(截至今天)而不是总计数,有什么想法吗?我喜欢这样的挑战。这里很晚了:明天应要求解释
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)
答案建议的另一种选择是(为简单起见,假设
eventlist
文件中EV01
和Event number one
之间有一个选项卡):
这里的关键步骤是date-f
将满是日期的文件转换为自纪元以来的秒数,因此我们可以将该数字除以一天中的秒数(86400)来计算自纪元以来的天数。找到每个事件最近的连续天数非常简单,我们可以通过组合使用join
(使用选项卡作为字段分隔符)和cut
,将较长的标签与每个事件计数相匹配
此解决方案比@glenn jackman的解决方案使用了更多的工具,但避免了对
mktime()
和strftime()
的需要,这可能不是在awk
的所有方言中都可以使用的。这很有效。你介意把这个看一遍吗?这样我就可以跟上了?我已经接受了这个解决方案,只是想确保我了解它是如何工作的。我不介意,但首先有没有什么具体的部分你不了解?特别是函数后面的两行:NR==FNR{id=$1;$1=“”;event[id]=$0;next}$NF!=eid{day=today;eid=$NF}NR==FNR
使用两个awk变量:NR
==当前记录的编号,FNR
,当前文件的当前记录编号。只有第一个文件可以NR==FNR
。此操作读取事件列表,将事件存储在关联数组中。NF
是当前记录中的字段数$
是返回字段值的运算符$1是第一个字段的值,$NF是最后一个字段的值eid
是一个用户定义的awk变量。未定义变量的行为类似于空字符串或数字0(取决于上下文)。当最后一个字段从上一个记录更改时,此操作开始。Simon,我尝试过此操作,但“加入”部分似乎不起作用。我收到一个错误,上面写着“join:multi-character tab”“”。我试图修改“join-t”旁边的间距,脚本运行,但我没有看到任何输出?@armohan:说服join
使用制表符作为分隔符很难,但按双引号之间的键对我有效。或者,您可以使用击键,也可以使用问题答案中显示的其他技术。
6 Event number one
4 Event number two
#!/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