下面是示例日志文件
aa001 2014/5/28 17:40
aa001 2014/5/28 18:40
bb002 2014/5/26 10:00
bb002 2014/5/28 7:00
bb002 2014/5/28 10:30
bb002 2014/5/28 11:31
bb002 2014/5/28 12:31
cc003 2014/5/28 11:25
dd004 2014/5/28 13:47
dd004 2014/5/28 16:53
dd004 2014/5/28 19:59
dd004 2014/5/28 20:02
dd004 2014/5/28 20:04
dd004 2014/5/28 22:04
ww005 2014/5/28 11:09
zz006 2014/5/28 9:27
zz006 2014/5/28 10:00
使用awk
,我喜欢只打印那些有多个登录会话的用户id,也只打印那些有第二个会话打开超过2小时的用户id。
我希望得到以下结果(userid以及针对该用户id的总登录)
bb002 5
dd004 6
。
- aa001和zz006有多个登录,但登录时间相差小于2小时
- 用户登录可以从不同的日期,例如bb002 2014年5月26日和2014年5月28日,
- 登录文件一般不超过100行。
提前感谢。
更新于June 01 2014由user3685993
下面是我尝试过的,我得到了我想要的结果,但是编码不是很简洁,像Jaypal的编码。
#!/bin/ksh93
#!/bin/bash
while read user dt tm
do
u_epoch_time=$( printf "%(%s)T" "${dt} ${tm}" )
c_epoch_time=$( printf "%(%s)T" "now" )
d_epoch_time=$(( $c_epoch_time - $u_epoch_time ))
[ $d_epoch_time -gt 7200 ] && printf "%s User has session checked for more than %.0f Hoursn" "$user" "$(( $d_epoch_time / 60 / 60 ))" done < sample.log > UserlogsReport.log
awk 'NF { id[$1]++; } END{ for (var in id) print var, "has", id[var], "sessions" }' sample.log > sessions_count.log
awk '{ if ($3 >=2) print }' sessions_count.log
Results
zz006 has 2 sessions
dd004 has 6 sessions
bb002 has 5 sessions
aa001 has 2 sessions
指出:
1. 我将所有登录与当前时间进行比较,因此在本例中,所有登录都超过两小时,因为登录日期比当前
早。2. 在第二个awk部分,我计数,然后输出会话计数>= 2。
使用GNU awk
:
awk '
(($1,$2) in check) {
split($2,d,///)
split($3,t,/:/)
time = mktime (d[1]" "d[2]" "d[3]" "t[1]" "t[2]" 00")
if (time - check[$1,$2] >= 7200) {
keep[$1]
}
else {
check[$1,$2] = time
}
}
{
split($2,d,///)
split($3,t,/:/)
time = mktime (d[1]" "d[2]" "d[3]" "t[1]" "t[2]" 00")
count[$1]++;
check[$1,$2] = time
}
END {
for (user in keep)
print user, count[user]
}' file
- 我们增加
count
数组为每个用户看到做count[$1]++
。 - 创建一个数组
check
,以用户和日期为键,时间为值(check[$1,$2] = $3
) 我们测试在数组中是否存在具有相同时间戳的user。如果是,我们在时间上做差异。如果大于或等于7200秒,则将用户存储在 - 我们对整个文件 继续这样做
- 在
END
块中,我们迭代keep
数组并打印用户以及count
数组的计数。
keep
数组中,否则将用户的新时间赋值到check
数组中。:
- 我们使用GNU
awk
mktime
函数,将日期和时间换算成秒,计算时间差,并检查时间差是否大于7200秒(即2小时)。