awk根据登录时间差(Timestamp)对重复的用户ID进行排序

时间:2014-05-29 03:51:56

标签: awk duplicates

以下是示例日志文件

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 

请注意。

  1. aa001和zz006有多次登录但两次登录之间的登录时间差小于2小时
  2. 用户登录可以来自不同的日期,例如bb002 2014/5/26和2014/5/28,
  3. 登录文件通常少于100行。
  4. 提前致谢。

    于2014年6月1日由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 Hours\n" "$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部分,我正在计算,然后输出有计数&gt; = 2的会话。

1 个答案:

答案 0 :(得分:0)

使用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
  • 我们测试数组中是否存在具有相同时间戳的用户。如果是的话,我们会及时做出改变。如果它大于或等于7200秒,我们将用户存储在keep数组中,否则我们会在check数组中为用户分配新时间。
  • 我们一直为整个文件执行此操作
  • END块中,我们迭代我们的keep数组并打印用户以及来自count数组的计数。

<强>更新

  • 我们使用GNU awk mktime函数通过将日期和时间转换为秒来计算时差,并检查差异是否大于7200秒(即2小时)。