问题陈述:
我仅需要在特定时间后才能从文件收集日志,该时间可以采用以下格式:“ 8月7日11:00:00.000”或“ 8月7日11:00:00”。这些日志位于其他txt文件中,格式为:
Aug 7 11:00:00 abc newsyslog[25714]: logfile turned over due to size>1024K
Aug 7 11:00:00.000 abc xyz lol
以此类推。
如何使用正则表达式提取此特定日期和时间,然后仅在指定时间后收集日志?除了正则表达式,还有其他更好的使用方法吗?
现在使用此:
import re
monthnames = "(?:Jan\w*|Feb\w*|Mar\w*|Apr\w*|May|Jun\w?|Jul\w?|Aug\w*|Sep\w*|Oct\w*|Nov(?:ember)?|Dec\w*)"
pattern1 = re.compile(r"(\d{1,4}[\/\\\-]+\d{1,2}[\/\\\-]+\d{2,4})")
pattern4 = re.compile(r"(?:[\d,. \-]*[,. \-])?%s(?:[\,\.\ \-]+[\d]+[stndrh]*)+[:\d]*[\ ]?(PM)?(AM)?([\ \-\+\d]{4,7}|[UTCESTGMT\ ]{2,4})*"%monthnames, re.I)
patterns = [pattern4, pattern1]
s='Aug 7 11:00:00.000'
for pattern in patterns:
print re.findall(pattern,s)
但是它什么也不返回,一个空列表!
需要帮助!
P.S-我只能在python中使用传统库,因为这是Junos的自动化脚本
答案 0 :(得分:1)
您绝对不需要正则表达式-在空白处进行简单拆分,并且收集前两个结果应该绰绰有余,即:
log_lines = ["Aug 7 11:00:00 abc newsyslog[25714]: logfile turned over due to size>1024K",
"Aug 7 11:00:00.000 abc xyz lol"] # we'll use a list as an example
for line in log_lines:
date_string = " ".join(line.split(None, 3)[:-1])
print(date_string)
# Aug 7 11:00:00
# Aug 7 11:00:00.000
现在,您可以使用datetime.datetime.strptime()
将其解析为本地日期时间对象,但是可能会受到格式的限制(即%b
仅是当前语言环境的缩写,而不是所有平台/版本都支持单位数字日期),因此,考虑到如此简单的结构,您可能需要在捕获的日期时间字符串进行解析之前重建它们,以最大程度地实现兼容性:
month_abbr = {"jan": 1, "feb": 2, "mar": 3, "apr": 4, "may": 5, "jun": 6,
"jul": 7, "aug": 8, "sep": 9, "oct": 10, "nov": 11, "dec": 12}
def parse_date(log_line):
mon, day, tim = line.split(None, 3)[:-1]
date_string = "{:02} {:02} ".format(month_abbr[mon.lower()], int(day)) + tim
try:
return datetime.datetime.strptime(date_string, "%m %d %H:%M:%S.%f")
except ValueError as e:
return datetime.datetime.strptime(date_string, "%m %d %H:%M:%S")
log_lines = ["Aug 7 11:00:00 abc newsyslog[25714]: logfile turned over due to size>1024K",
"Aug 7 11:00:00.000 abc xyz lol"] # we'll use a list as an example
for line in log_lines:
date_object = parse_date(line)
print(date_object)
# 1900-08-07 11:00:00
# 1900-08-07 11:00:00
注意:您的日期时间对象将以1900
作为年份,因为您的日志没有年份信息。第二个日期时间对象也包含其微秒数据,只是没有使用datetime.datetime
对象的默认表示而打印出来。
现在,您可以将这些日期时间对象与其他日期时间对象进行比较,并过滤掉/打印/做任何符合条件的行,例如如果只想在之后 Aug 7
之后创建日志:
log_lines = ["Aug 7 11:00:00 abc newsyslog[25714]: logfile turned over due to size>1024K",
"Aug 7 11:00:00.000 abc xyz lol",
"Aug 8 11:00:00 foo bar"] # we'll use a list as an example
min_date = datetime.datetime(1900, 8, 8) # minimum date set to Aug 8
for line in log_lines:
if parse_date(line) >= min_date:
print(line)
# Aug 8 11:00:00 foo bar
答案 1 :(得分:1)
我认为正则表达式是一个过大的功能,我会提取日期部分,例如:
' '.join(line.split()[0:3])
然后将strptime()与较长的格式一起使用,捕获异常,并为较短的格式尝试使用strptime:
from datetime import datetime
def get_date(date_str):
try:
return datetime.strptime(date_str, '%b %d %H:%M:%S.%f')
except ValueError:
return datetime.strptime(date_str, '%b %d %H:%M:%S')