如何按日期时间范围grep?

时间:2011-04-04 01:09:02

标签: python bash sed awk grep

我的日志文件如下:

2011-03-21 00:01 xxxx
2011-03-22 04:05 xxxx
....
2011-03-25 10:12 xxxx
....
2011-04-04 12:23 xxxx

我想要一个需要2个参数作为日期范围的脚本,例如:

grep-date-range.sh 2011-03-25 2011-04-02

将在[2011-03-25,2011-04-02]中找到所有日志。我知道一个特定的情况我可以使用通配符,但在我看来这并不普遍。有人可以给我一个解决方案吗?

修改 Python脚本也可以接受。

4 个答案:

答案 0 :(得分:3)

他的情况是编写一个简短的Python脚本可能会更好。语言中的高级日期操作功能非常方便。

下面的脚本非常简单 - 通过更多的工作,它可以处理当地时间差异,夏令时等等。

#! /usr/bin/python
import sys
from datetime import datetime
d_format = "%Y-%m-%d"

try:
    start = datetime.strptime(sys.argv[1], d_format)
    end = datetime.strptime(sys.argv[2], d_format) 
except (TypeError, IndexError):
    sys.stderr.write("Example: grep-date-range.py 2011-03-25 2011-04-02 \n")

for line in sys.stdin:
    try:
        date = datetime.strptime(line.split()[0], d_format)
        # suit the <=, <, comparisons bellow to your needs:
        if start <= date < end:
            sys.stdout.write(line)
    except (ValueError, IndexError):
        pass 

答案 1 :(得分:3)

sed -n "/$1/,/$2/p" $3

称之为:

fromTo "2011-03-25" "2011-04-02" foo.log

SED

  • -n:无输出
  • / from /,/ to /:匹配的模式
  • p:print

日期必须存在于文件中,如果您将2011-03-24和2011-03-26作为日期,则无法使用。它是字符串匹配,而不是日期匹配。 你不需要引用,但我碰巧有另一种日期格式,所以我有我的测试(“3月23日”等等)。

答案 2 :(得分:1)

好的,我终于明白了。基本的想法是使用sort -m合并给定的日期,使用sed提取那些已知的行(感谢“用户未知”的建议)。如果数据文件尚未排序,请先对其进行排序。这里的假设是YYYY-MM-DD是一个常数,否则这将不起作用。

您可以使用mktemp代替/tmp/startstop以及比“START”和“END”更独特的字符串,使其更加强大。

/tmp/data显然是您的数据文件。

#!/bin/bash

START=$1
END=$2

echo $START START > /tmp/startstop
echo $END END >> /tmp/startstop

sort -m /tmp/data /tmp/startstop | sed -n '/START/,/END/p'

答案 3 :(得分:0)

好吧,因为你的日期已经“可以排序”了,

#!/bin/bash

a=2011-03-25
b=2011-06-02
a=${a//-/} # you can remove the dashes or not, up to you
b=${b//-/} # you can remove the dashes or not, up to you
awk -va=$a -vb=$b '{
    # save the first field if going to remove dash, 
    old=$1 
    # you can remove the dashes or not, up to you. Because your date is sortable
    # the dash will not matter.
    gsub(/-/,"",old) # for removing dash
    if( old >= a && old <=b ){ 
        # or use if ($1 >=a && $1 <=b ) (if not removing dash)
        print
    }
}' file