如何使用时间戳进行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
我想了解xyz
之后20121912-08:15:55
的出现情况,在这种情况下应该是2
。
执行grep -c "xyz" filename
读取整个文件并给出结果。我希望在上次更新或使用时间戳后执行此操作。
答案 0 :(得分:2)
试试这个单行:
awk '$NF=="xyz"&&$1>="20121912-08:15:55"{x++;}END{print x}' file
答案 1 :(得分: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
答案 2 :(得分:1)
对于您想要的最早日期,这只是一种黑客攻击,只有grep
,然后使用-A
打印所有行,然后通过管道传输到grep -c xyz
:
$ fgrep -A 100 '20121912-08:15:55' file | fgrep -c 'xyz'
2
注意:fgrep
只是固定字符串grep
,因为您没有使用regex
模式,这与执行grep -F
相同。
由于使用sed
来打印日期中的所有行,所以不那么愚蠢,这样您就不需要确保-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
答案 3 :(得分:1)
您可以告诉sed从给定范围(起点和终点)的文件中打印行 - 该范围可以是正则表达式或行号表示法。
根据您的需要,应该这样做:
$ sed -n '/20121912-08:15:55/,$p' input.txt | grep -c xyz
此处起始点由日期给出,视为正则表达式,终点是最后一行符号$
。 p
告诉sed打印给定范围内的行。 sed的-n
选项告诉它不打印它正在处理的行。
答案 4 :(得分: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}
'
答案 5 :(得分: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
HTH