如何解析匹配字符串所有行的文件并跟踪计数?

时间:2017-06-24 21:19:12

标签: python

我们有一个包含以下行的文件, 我们需要找到所有带有“Error”消息类型的行。 保存邮件及其计数并按照计数的降序打印邮件,任何人都可以提供有关如何执行此操作的指导吗?

file.txt的

<TIMESTAMP><MESSAGETYPE><MESSAGE>
<4:02><ERROR><Error message1>
<14:13><Error><Error message2>
<10:03><Warning><Warning message1>
<12:03><Warning><Warning message2>

代码: -

4 个答案:

答案 0 :(得分:4)

  1. 打开文件并阅读所有行
  2. with open("file.txt") as f:  
        lines = f.read().splitlines()
    
    1. 列出包含“错误”一词
    2. 的行

      data = [ line.lstrip('<').rstrip('>').split('><') for line in lines if 'Error' in line  ]
      
      1. data列表
      2. 获取时间和消息项

        errors = [ { 'time' : line[0], 'message': line[-1] } for line in data ]  
        
        1. 按“时间”降序排列errors列表
        2. errors.sort(key=lambda e : e['time'], reverse=True)  
          

          请注意,errors是一个词典列表,如果您愿意,可以使用列表 如果要打印结果:

          print '\n'.join( 'Time {:8} Error {}'.format(e['time'], e['message']) for e in errors )
          

          输出:

          Time: 4:02   Error: Error message1
          Time: 14:13  Error: Error message2
          

答案 1 :(得分:1)

对于类似的任务,我使用了下一个技巧:

fname = "summary.log"
with open(fname) as f:
    content = f.readlines()
content = [x.strip() for x in content]
commits = []

def onHeader(obj):
    date = obj.group(1)
    time = obj.group(2)
    commits.append(CCommitInfo(date, time))

def onFile(obj):
    added = int(obj.group(1))
    removed = int(obj.group(2))
    commits[-1].changed(added, removed)

matchers = []
matchers.append((re.compile(r"(.+?)\s(.+?)\s\+\d+$"), onHeader))
matchers.append((re.compile(r"^(\d+)\t(\d+).+\.(php|pas)"), onFile))

def match(s):
    for x in matchers:
        r = x[0].search(s)
        if r:
            x[1](r)
            break

for x in content:
    match(x)

对不起代码&#34;原样&#34;。如您所见,我只是添加matchers对regexp-callback并将它们匹配到每一行。简单而有力。

答案 2 :(得分:1)

你可以这样做:

from collections import defaultdict
import operator
import re

def find_error_message(string):
    match = re.search(r"<\d{1,2}:\d{2}><(ERROR|Error)><(?P<message>[a-zA-z0-9 ]*)>(\n)?", string)
    if match:
        return match.group("message")

messages = defaultdict(int)
with open(r"log.txt", "r") as fh:
    lines = fh.readlines()

lines.pop(0)
for line in lines:
    message = find_error_message(line)
    if message:
        messages[message] += 1
for message, count in sorted(messages.items(), key=operator.itemgetter(1), reverse=True):
    print("{}: {}".format(message, count))

find_error_message函数只是检查文件中的每一行以查看它是否是错误,如果错误则返回错误消息。

文件log.txt已打开,其中的所有行都被读入列表。然后我们pop第一个元素,即标题。然后我们遍历每一行,检查它是否有错误信息。如果有,我们会增加该特定错误消息的计数。

一旦我们检查了所有行,我们对字典messages进行排序,除了我们想要a)按字典值对其进行排序,以及b)反向排序。

最后,我们按顺序打印已排序的元素及其发生的次数。

答案 3 :(得分:1)

使用Counter

from re import compile, IGNORECASE
from collections import Counter
from operator import itemgetter

parse = compile(r'<(?P<ts>.*)><(?P<level>ERROR)><(?P<message>.*)>', IGNORECASE)

with open('file.txt') as f:
    logs = filter(None, map(parse.match, f))
    counts = Counter(log.group('message') for log in logs)

print sorted(counts.items(), key=itemgetter(1), reverse=True)


>>> [('Error message1', 1), ('Error message2', 1)]