2012-06-22 10 views
1

У меня есть текстовый файл, который необходимо проанализировать. Каждая строка в файле имеет такой вид:Анализ текстового файла в Python

7:06:32 (slbfd) IN: "lq_viz_server" [email protected] 

7:08:21 (slbfd) UNSUPPORTED: "Slb_Internal_vlsodc" (PORT_AT_HOST_PLUS ) [email protected] (License server system does not support this feature. (-18,327)) 

7:08:21 (slbfd) OUT: "OFM32" [email protected] 

Мне нужно, чтобы пропустить метку времени и (slbfd) и только сохранить количество линий с IN и OUT. Кроме того, в зависимости от имени в кавычках мне нужно увеличить количество переменных для разных переменных, если строка начинается с OUT и уменьшает количество переменных в противном случае. Как мне это сделать в Python?

+1

[что вы пробовали] (HTTP: // whathaveyoutried .com) до сих пор? где вы застряли? – Aprillion

+0

Вы можете проанализировать строку с помощью команды .split(). У вас есть какой-либо код, пытающийся разобрать одну строку? После того, как вы сможете разобрать одну строку, вы сможете разобрать их все. После этого просто вопрос проверки правильных элементов в каждой строке с логикой –

ответ

1

У вас есть два варианта:

  1. Используйте .split() функцию string (как указано в комментариях)
  2. Используйте re module для регулярных выражений.

Я бы предложил использовать модуль re и создать шаблон с названными группами.

Рецепт:

  • сначала создать шаблон с re.compile(), содержащие названные группы
  • сделать for петлю на файл, чтобы получить строки использовать .match() од
  • созданный объект шаблона на каждом использовании линии .groupdict() от
  • Объект возвращенного объекта для просмотра ваших значений
1

Если я считаю, что файл разделен на строки (я не знаю, правда ли это), вы должны применить функцию split() к каждой строке. Вы будете иметь это:

["7:06:32", "(slbfd)", "IN:", "lq_viz_server", "[email protected]"] 

И тогда я думаю, вы должны быть способны применить любую логику сравнения значения, что вам нужно.

1

я сделал некоторые дикие предположения о вашей спецификации, и вот пример код, чтобы помочь вам начать:

objects = {} 
with open("data.txt") as data: 
    for line in data: 
     if "IN:" in line or "OUT:" in line: 
      try: 
       name = line.split("\"")[1] 
      except IndexError: 
       print("No double quoted name on line: {}".format(line)) 
       name = "PARSING_ERRORS" 
      if "OUT:" in line: 
       diff = 1 
      else: 
       diff = -1 
      try: 
       objects[name] += diff 
      except KeyError: 
       objects[name] = diff 
print(objects) # for debug only, not advisable to print huge number of names 
+0

просто хорошая работа –

5

других ответы с регулярным выражением и расщеплением линии будет получить работу, но если вы хотите полностью поддерживаемое решение, которое будет расти вместе с вами, вы должны построить грамматику. Я люблю pyparsing для этого:

S =''' 
7:06:32 (slbfd) IN: "lq_viz_server" [email protected] 
7:08:21 (slbfd) UNSUPPORTED: "Slb_Internal_vlsodc" (PORT_AT_HOST_PLUS ) [email protected] (License server system does not support this feature. (-18,327)) 
7:08:21 (slbfd) OUT: "OFM32" [email protected]''' 

from pyparsing import * 
from collections import defaultdict 

# Define the grammar 
num = Word(nums) 
marker = Literal(":").suppress() 
timestamp = Group(num + marker + num + marker + num) 
label = Literal("(slbfd)") 
flag = Word(alphas)("flag") + marker 
name = QuotedString(quoteChar='"')("name") 

line = timestamp + label + flag + name + restOfLine 
grammar = OneOrMore(Group(line)) 

# Now parsing is a piece of cake! 
P = grammar.parseString(S) 
counts = defaultdict(int) 

for x in P: 
    if x.flag=="IN": counts[x.name] += 1 
    if x.flag=="OUT": counts[x.name] -= 1 

for key in counts: 
    print key, counts[key] 

Это дает в качестве вывода:

lq_viz_server 1 
OFM32 -1 

Какой будет выглядеть более внушительно, если ваш файл журнала образец был длиннее. Красота решения pyparsing - возможность адаптироваться к более сложному запросу в будущем (например, захватить и проанализировать временную метку, вывести адрес электронной почты, разобрать коды ошибок ...). Идея состоит в том, что вы пишете грамматику независимо от запроса - вы просто конвертируете исходный текст в удобный для компьютера формат, абстрагируя реализацию разбора от использования.

+0

+1: более надежное решение (но требует внешнего модуля). –

0

В режиме только получить «эр сделано со стандартным распределением, это работает:

import re 
from collections import Counter 
# open your file as inF... 
count=Counter() 
for line in inF: 
    match=re.match(r'\d+:\d+:\d+ \(slbfd\) (\w+): "(\w+)"', line) 
    if match: 
     if match.group(1) == 'IN': count[match.group(2)]+=1 
     elif match.group(1) == 'OUT': count[match.group(2)]-=1 

print(count) 

Печать:

Counter({'lq_viz_server': 1, 'OFM32': -1}) 
Смежные вопросы