如何按日期时间范围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
我想写一个脚本,这个脚本需要两个参数,表示日期范围,比如:
grep-date-range.sh 2011-03-25 2011-04-02
它会找到所有在[2011-03-25, 2011-04-02]之间的日志。我知道在特定情况下可以用通配符,但我觉得这不是一个通用的方法。有没有人能给我一个解决方案?
补充: Python脚本也可以接受。
5 个回答
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'
2
sed -n "/$1/,/$2/p" $3
调用它:
fromTo "2011-03-25" "2011-04-02" foo.log
sed
- -n: 不输出任何内容
- /from/,/to/: 要匹配的模式
- p: 打印
文件中必须存在这些日期,如果你只在里面有2011-03-24和2011-03-26,这个方法就不管用了。它是字符串匹配,而不是日期匹配。你不需要加引号,但我碰巧有另一种日期格式,所以在我的测试中用了(比如“Mar 23”等)。
2
在这种情况下,写一个简单的Python脚本可能会更好。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