在LINUX命令中检索特定时间段内的数据行

时间:2017-12-09 16:07:54

标签: linux awk sed

我正在开发一些LINUX代码来过滤cus.txt文件中的一些数据。下面以文本格式显示表格

12/3/2017  13:25:16  SAM      reject
12/3/2017  13:25:26  NEEL     pass
12/3/2017  13:25:58  SAM      pass
12/3/2017  14:55:11  COOK     pass
12/13/2017 21:25:45  ANDRUE   pass
12/15/2017 23:46:31  FLINTOF  pass
12/19/2017 16:25:51  KEVIN    pass
12/20/2017 13:15:35  JHON     reject
12/20/2017 13:15:25  ADEM     pass
12/20/2017 13:15:51  JHON     pass
12/22/2017 15:39:09  KEVIN    pass
12/25/2017 19:25:28  SIMON    reject
12/25/2017 19:25:31  JHON     pass
12/25/2017 19:25:38  COOK     pass
12/25/2017 19:25:50  SIMON    pass
12/26/2017 22:19:20  SAM      pass
12/27/2017 20:12:55  KEVIN    pass

我需要的是, 如果你满足每一个"拒绝"在第4列中的单词,它应检查名称列中的名称并过滤下一个"传递"在30秒的时间段内使用相同的名称。下面显示了我的linux代码。

awk 'function get_time(d_str){ split(d_str, d, /[/:[:space:]]/);
return mktime(sprintf("%d %d %d %d %d %d",d[3],d[1],d[2],d[4],d[5],d[6])) }$5=="pass" && status=="reject" &&
(get_time(prev_date)-get_time($1" "$2))<=30;{ prev_date=$1" "$2;
status=$5 }' cus.txt  

使用此代码,我可以在结果下方进行过滤。这不是我需要的。

enter image description here

以上不是我要求的结果。下面显示了我需要的结果:

enter image description here

2 个答案:

答案 0 :(得分:2)

虽然您可以根据需要使用awk,但您也可以使用简单的shell脚本和date -d来计算上一个reject和下一个pass之间的时差使用相同的name。然后测试差异是否小于或等于30秒,如果是,则打印该行,例如

#!/bin/bash

rdate=   ## empty variables to use for reject
rtime=
rname=

while read -r dt tm nm res; do      ## read date time name result
    if [ "$res" = "reject" ]; then  ## if result "reject"
        rdate="$dt"                 ## save date time name
        rtime="$tm"
        rname="$nm"
    ## elif result is pass, if rname set check name = last reject name
    elif [ -n "$rname" ] && [ "$nm" = "$rname" ]; then 
        ## compute time difference between reject and current
        tmdiff=$(( $(date -d "$dt $tm" +%s) - $(date -d "$rdate $rtime" +%s) ))
        ## if less than or equal to 30 output line
        [ "$tmdiff" -le "30" ] && \
            printf "%-9s %s %-7s %s\n" "$dt" "$tm" "$nm" "$res"
    fi
done <cus.txt

示例输出

$ bash cus.sh
12/20/2017 13:15:51 JHON    pass
12/25/2017 19:25:50 SIMON   pass

答案 1 :(得分:1)

GNU awk 解决方案:

awk 'function get_time(d_str){ 
         split(d_str, d, /[/:[:space:]]/); 
         return mktime(sprintf("%d %d %d %d %d %d",d[3],d[1],d[2],d[4],d[5],d[6])) 
     }
     $4=="pass" && $3==name && (get_time($1" "$2)-get_time(prev_date))<=30;
     $4=="reject"{ prev_date=$1" "$2; name=$3 }' file

输出:

12/20/2017 13:15:51  JHON     pass
12/25/2017 19:25:50  SIMON    pass