用于根据登录时间差(时间戳)对重复用户标识进行排序的awk

用于根据登录时间差(时间戳)对重复用户标识进行排序的awk,awk,duplicates,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 d

下面是示例日志文件

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的总登录次数)

注意

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

    用户3685993于2014年6月1日更新 下面是我尝试过的,我得到了我想要的结果,但是编码不是很简洁,就像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    
    
    #/垃圾箱/ksh93
    #!/bin/bash
    当读取用户dt tm时
    做
    时间=$(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”用户已检查会话超过%.0f小时\n“$User”“$($d_epoch_time/60/60))”完成UserlogsReport.log
    awk'NF{id[$1]+;}END{for(id中的var)print var,“has”,id[var],“sessions”}sample.log>sessions_count.log
    awk“{if($3>=2)print}”会话\u count.log
    后果
    zz006有2个会话
    dd004有6个会话
    bb002有5个会话
    aa001有2个会话
    
    注:
    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[$1]+
      为每个用户增加一个
      count
      数组
    • 创建一个数组
      check
      ,用户和日期作为键,时间作为值(
      check[$1,$2]=$3
    • 我们测试数组中是否存在具有相同时间戳的用户。如果是这样的话,我们在时间上做了区别。如果大于或等于7200秒,我们将用户存储在
      keep
      数组中,否则我们将在
      check
      数组中为用户分配新时间
    • 我们对整个文件都这样做
    • END
      块中,我们迭代
      keep
      数组并打印用户以及
      count
      数组中的计数
    更新

    • 我们使用GNU
      awk
      mktime
      函数通过将日期和时间转换为秒来计算时间差,并检查差值是否大于7200秒(即2小时)
    你好,Martin Konecny,我试着将代码分为两部分:1。输出登录时间超过24小时的用户ID,我有epoch功能ksh93',同时读取用户v1 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 86400]&printf s用户已登录%.0f天\n“$user”“$($d_epoch_time/60/60/24))”完成1)for(i=1;i可以编辑您的问题,使用该代码使其格式正确。@user3685993您是否尝试了我提供的以下脚本?@jaypal非常感谢您的帮助。您的代码非常简短。但它适用于示例,但我尝试了更改日期和分钟时间,但结果是一致的。例如,下面更改为用户bb002,有没有课时,相差2小时,但我仍然得到与“5”相同的结果。bb002 2014/5/28 7:30 bb002 2014/5/28 9:10 bb002 2014/5/28 7:30 bb002 2014/5/28 8:30 bb002 2014/5/28 9:00顺便说一句,我已经更新了代码,你能帮我用更智能的方式重写吗。我不是Linux或任何其他代码用户,只是在探索“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