7

如何grep使用时间戳进行计数?

示例:如果我有一个文件,我xyz每次都在其中搜索一个值。该文件会定期更新。

20121912-07:15:55 abc cbfr xyz
20121912-07:16:40 mni cbfr xyz
-----------
-----------
-----------


20121912-08:15:55 gty cbfr xyz
20121912-08:20:55 jui uio xyz

我想找出xyz20121912-08:15:55这种情况下应该是2.

执行 agrep -c "xyz" filename读取整个文件并给出结果。我想在最后一次更新之后或使用时间戳来做。

4

6 回答 6

2

试试这个单行:

awk '$NF=="xyz"&&$1>="20121912-08:15:55"{x++;}END{print x}' file
于 2012-12-19T15:26:39.950 回答
2

我假设您想查找出现的模式:“xyz”,其中日期/时间值大于或等于指定的日期/时间:“20121912-08:15:55”。这就是我使用GNU awk. 像这样运行:

awk -v pattern="xyz" -v time="20121912-08:15:55" -f script.awk file

内容script.awk

BEGIN {
    stamp = convert(time)
}

$0 ~ pattern && convert($1) >= stamp {
    i++
}

END {
    print i
}

function convert(var) {

    x = "(....)(..)(..)-(..):(..):(..)"
    y = "\\1 \\3 \\2 \\4 \\5 \\6"

    return mktime(gensub(x,y,"",var))
}

结果:

2

或者,这是单线:

awk -v pattern="xyz" -v time="20121912-08:15:55" 'BEGIN { stamp = convert(time) } $0 ~ pattern && convert($1) >= stamp { i++ } END { print i } function convert(var) { return mktime(gensub(/(....)(..)(..)-(..):(..):(..)/,"\\1 \\3 \\2 \\4 \\5 \\6","",var)) }' file
于 2012-12-19T23:10:42.430 回答
1

您可以告诉 sed 从给定范围(起点和终点)的文件中打印行 - 范围可以是正则表达式或行号表示法。

根据您的需要,应该这样做:

$ sed -n '/20121912-08:15:55/,$p' input.txt | grep -c xyz

这里起点由日期给出,被视为正则表达式,终点是最后一行符号$p告诉 sed 打印给定范围内的行。-nsed 选项告诉它不打印正在处理的行。

于 2012-12-19T15:56:41.553 回答
1

从 Kent 的回答中汲取灵感,这里有一些 Perl 将奇数时间戳转换为 YYYYMMDD 格式:

ts="20121912-08:15:55" patt="xyz" perl -lane  '
    BEGIN {
        ($wanted_ts = $ENV{ts}) =~ s/^(....)(..)(..)/$1$3$2/;
        $pattern = qr{$ENV{patt}};
    }
    ($this_ts = $F[0]) =~ s/^(....)(..)(..)/$1$3$2/;
    $count++ if $this_ts ge $wanted_ts and /$pattern/;
    END {print $count}
'
于 2012-12-19T19:52:40.093 回答
1

这是一种 hack,但仅grep适用于您想要的最早日期,然后使用管道打印所有行,-A然后通过管道传输到grep -c xyz

$ fgrep -A 100 '20121912-08:15:55' file | fgrep -c 'xyz'
2

注意:fgrep只是固定字符串grep,因为您不使用regex模式,它与做grep -F.

由于不那么 hacky 的方式是使用sed从日期开始打印所有行,这样您就不需要确保值 to-A将涵盖文件的长度:

$ sed -n '/20121912-08:15:55/,$p' file | fgrep -c 'xyz'
2

这当然假设您的文件是按时间戳排序的,如果不是那么:

$ sort file | sed -n '/20121912-08:15:55/,$p' | fgrep -c 'xyz'
2
于 2012-12-19T15:24:58.950 回答
0

嗯,赶紧写一篇:

 grep xyz filename | sed -r 's/^([^ ]+).*/ 20121912-08:15:55 <= \1/' | sed -r 's/([0-9]{4})([0-9]{2})([0-9]{2})/\1\3\2/g' | sed 's/[-:]//g' | bc | grep 1 | wc -l

它非常难看(我不是 sed 也不是命令行大师)并且可能会缩短,但这是一种方法。下面的解释:

  grep xyz filename                                  //gets all interseting lines
| sed -r 's/^([^ ]+).*/ 20121912-08:15:55 <= \1/'    //transform them into 
                                                       //comparison with the 
                                                       //date you want
| sed -r 's/([0-9]{4})([0-9]{2})([0-9]{2})/\1\3\2/g' //invert day and month
| sed 's/[-:]//g'                                    //remove separators
| bc                                                 //ask bc result 
| grep 1                                             //get true results only
| wc -l                                              //and finally count them

对于您示例的最后一行,这些步骤将给出:

20121912-08:20:55 jui uio xyz                  //grep 'xyz'
20121912-08:15:55 <= 20121912-08:20:55         //sed
20121219-08:15:55 <= 20121219-08:20:55         
20121219081555 <= 20121219082055               
1                                              //result from bc

高温高压

于 2012-12-19T16:19:27.557 回答