Разбор файла журнала с применением условия

1

У меня есть файл журнала отладки, как вы можете видеть ниже:

Образец файла:

DEBUG: Fri Dec  7 06:49:14 2018:16920 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16920: start <ID>
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "output
output output
output"
DEBUG: extra lines

Я хочу получить только идентификаторы и окончательный вывод, как показано ниже.

Ожидаемый результат:

<ID> "output
output output
output"

Я хотел бы сделать это в Python или Bash. Любая помощь будет оценена. Спасибо

Текущий код работает только для "окончательного вывода". но я также хочу получить идентификаторы, и должен быть способ различать (разделитель) для каждого идентификатора и его вывода.

stream=open("debuglog.txt","r")
lines=stream.readlines()

flag = 0
for i in lines:
    if "DEBUG:" in i:
        flag = 0
    if "final output is" in i:
        flag = 1
    if flag:
        print(i)
  • 2
    Что вы пробовали? Пожалуйста, оставьте свой код.
  • 0
    Покажите нам, что вы пробовали до сих пор?
Показать ещё 2 комментария
Теги:
text-processing

3 ответа

1
Лучший ответ

С питоном, как насчет:

#!/usr/bin/python

import re
text = open("logfile", "r").read()

regex = r'start (.+?)$.*?Final output is (.+?)(?:(?=\nDEBUG)|\Z)'
for m in re.finditer(regex, text, re.MULTILINE|re.DOTALL):
    for i in m.groups():
            print(i.replace('\n', ' '))

Входной файл журнала:

DEBUG: Fri Dec  7 06:49:14 2018:16920 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16920: start <ID>
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "output
output output
output"
DEBUG: extra lines

DEBUG: Fri Dec  7 06:49:14 2018:16920 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16920: start <ID2>
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "output2
output+ output/
output2"

И вывод:

<ID>
"output output output output"
<ID2>
"output2 output+ output/ output2" 
  • Первое число в регулярном выражении захватывает любые символы сразу после start и перед новой строкой и сохраняет строку в 1st group.
  • 2-е число в регулярном выражении также захватывает любые символы сразу после того, как Final output is перед DEBUG или концом строки, и сохраняет строку во 2nd group. Новые строки могут быть включены в строку благодаря опции re.DOTALL.
  • Третьи парены являются якорями нулевой длины и не входят в группу захвата.

РЕДАКТИРОВАТЬ

Обновленная версия ниже обрабатывает несколько "окончательных выходных данных" для одного идентификатора и отображает только последний вывод для каждого идентификатора:

#!/usr/bin/python

import re
text = open("logfile", "r").read()

regex = r'start (.+?)$(.+?)(?:(?=DEBUG[^\n]+?start)|\Z)+'
regex2 = r'Final output is (.+?)(?:(?=\nDEBUG)|\Z)'

for m in re.finditer(regex, text, re.MULTILINE|re.DOTALL):
    print m.group(1)
    m2 = re.finditer(regex2, m.group(2), re.MULTILINE|re.DOTALL)
    print list(m2).pop().group(1).replace('\n', ' ')

входной файл журнала:

DEBUG: Fri Dec  7 06:49:14 2018:16920 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16920: start <ID1>
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "output
output output
output"
DEBUG: extra lines
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "this
is the last output
for <ID1>"
DEBUG: extra lines

DEBUG: Fri Dec  7 06:49:14 2018:16920 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16920: start <ID2>
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "output2
output+ output/
output2"

и вывод:

<ID1>
"this is the last output  for <ID1>"
<ID2>
"output2 output+ output/ output2"

Я разделил извлечение подстрок в два этапа:

  1. извлечь идентификатор и оставшийся текст (который может содержать дополнительные строки). Это обрабатывается с помощью regex.
  2. извлечь подстроки "конечного вывода" из "оставшегося текста" выше. Это обрабатывается с помощью regex2.

Затем выберите последний "окончательный результат" и отобразите.

РЕДАКТИРОВАТЬ

Версия ниже подавляет сообщение (я), которое содержит ключевое слово:

#!/usr/bin/python

import re
text = open("logfile", "r").read()

exclude = 'xyz'     # keyword to suppress the output

regex = r'start (.+?)$(.+?)(?:(?=DEBUG[^\n]+?start)|\Z)+'
regex2 = r'Final output is (.+?)(?:(?=\nDEBUG)|\Z)'
#regex = r'start (.+?)$.*?Final output is (.+?)(?=\nDEBUG)'
#for m in re.finditer(regex, text, flags=(re.MULTILINE|re.DOTALL)):
for m in re.finditer(regex, text, re.MULTILINE|re.DOTALL):
    print m.group(1)
    m2 = re.finditer(regex2, m.group(2), re.MULTILINE|re.DOTALL)
    message = list(m2).pop().group(1).replace('\n', ' ')
    if message.count(exclude):
        print 'error:' + exclude
    else:
        print message

Пример файла журнала:

DEBUG: Fri Dec  7 06:49:14 2018:16920 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16920: start <ID1>
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "output
output output
output"
DEBUG: extra lines
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "this
is the last output
for ID1"
DEBUG: extra lines

DEBUG: Fri Dec  7 06:49:14 2018:16920 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16920: start <ID2>
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "output2
output+ output/
output2"
DEBUG: extra lines

DEBUG: Fri Dec  7 06:49:14 2018:16920 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16920: start <ID3>
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "this message
contains the word xyz"
DEBUG: extra lines

Выход:

<ID1>
"this is the last output  for ID1"
<ID2>
"output2 output+ output/ output2"
<ID3>
error:xyz
  • 0
    Большое спасибо. это очень точно.
  • 0
    Что я могу сделать, если есть несколько «окончательных выходных данных» для одного <ID>, и я хочу получить только последний.
Показать ещё 5 комментариев
3

Пример файла журнала:

DEBUG: Fri Dec  7 06:49:14 2018:16920 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16920: start 12324
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "output output output output"
DEBUG: extra lines

Пожалуйста, найдите код. Кроме того, я предполагаю, что у вас есть только один экземпляр каждого идентификатора и выходных

import sys, re

stream=open("log","r")
lines=stream.readlines()


flag_ID = 0
flag_output = 0
flag_print = 1
for i in lines:
    ID = re.match("DEBUG: [\w :]* start (\d+)", i)
    output = re.match("DEBUG: [\w :]* Final output is \"([\w ]*)\"", i)
    if ID:
        flag_ID = 1
        value_ID = ID.group(1)
    if output:
        flag_output = 1 
        value_output = output.group(1)
    if flag_output == 1 and flag_ID == 1 and flag_print == 1:
        print "{0} {1}".format(value_ID, value_output)
        flag_print = 0

выход

12324 output output output output

Пожалуйста, отметьте и примите, если это решит вашу проблему;)

  • 0
    Спасибо за решение. Однако существует одна проблема, поскольку выходные данные могут быть любыми (буквы, цифры, символы), поэтому регулярное выражение "\" ([\ w] *) \ "" не работает должным образом. Я не хорошо с регулярным выражением. Не могли бы вы помочь мне с регулярным выражением, которое может извлекать разных персонажей до первого появления "DEBUG"
  • 0
    Вы не можете обратиться к ссылке ниже, чтобы проверить вашу строку regex101.com/r/jE4cE4/62
Показать ещё 5 комментариев
0

С Perl вы можете сделать это с помощью одной строки, если файл может поместиться в памяти.

/tmp> cat debug.log
DEBUG: Fri Dec  7 06:49:14 2018:16920 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16920: start <ID1>
DEBUG: Fri Dec  7 06:49:14 2018:16920: Final output is "output
output output
output"
DEBUG: extra lines
DEBUG: Fri Dec  7 06:49:14 2018:16921 extra text
DEBUG: Fri Dec  7 06:49:14 2018:16921: start <ID2>
DEBUG: Fri Dec  7 06:49:14 2018:16921: Final output is "output output output output"
DEBUG: extra lines
/tmpl>
/tmp> perl -0777 -ne ' while(/^DEBUG(.+?)start (\S+).*?DEBUG.+?Final output is \"(.+?)\"/smg) { print "$2 $3\n" } ' debug.log
<ID1> output
output output
output
<ID2> output output output output
/tmp>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню