py.Net.JS Ответов: 2

Как создать Поиск регулярных выражений Python для извлечения определенных значений из журналов сервера


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

2017-03-18 13:24:05,791 INFO [STDOUT] SUB Request Status :Resubmitted INBIOS_ABZ824
2017-03-12 13:24:05,796 INFO [STDOUT] SUB Submit Status :Resubmitted INDROS_MSR656
2017-04-12 13:24:05,991 INFO [STDOUT] SUB Request Status :Resubmitted INHP_GSN848

и мне нужно найти журнал и извлечь следующие значения,

2017-03-18 13:24:05,791 INBIOS_ABZ824
2017-03-12 13:24:05,796 INDROS_MSR656
2017-04-12 13:24:05,991 INHP_GSN848

Я использую следующий код, но он извлекает полную строку, где присутствуют такие строки (INBIOS_ABZ824). Как я могу извлечь только указанные значения из журнала, как указано выше, пожалуйста, поделитесь своими мыслями

Что я уже пробовал:

import os
import re

# Regex used to match relevant loglines (in this case)

line_regex = re.compile(r"[A-Z]+TECH_[A-Z]+[0-9]+", re.IGNORECASE)


# Output file, where the matched loglines will be copied to
output_filename = os.path.normpath("output.log")
# Overwrites the file, ensure we're starting out with a blank file
with open(output_filename, "w") as out_file:
    out_file.write("")

# Open output file in 'append' mode
with open(output_filename, "a") as out_file:
    # Open input file in 'read' mode
    with open("ServerError.txt", "r") as in_file:
        # Loop over each log line
        for line in in_file:
            # If log line matches our regex, print to console, and output file
            if (line_regex.search(line)):
                print(line)
                out_file.write(line)

2 Ответов

Рейтинг:
16

Jochen Arndt

Итак, вы хотите получить отметку времени и часть в конце?

Хотя это можно сделать с регулярными выражениями, это было бы намного проще (и быстрее) с классическими строковыми операциями.

Отметка времени находится в начале строки с фиксированной длиной 23, а конечная часть-после последнего пробела в строке (непроверенная):

# Get index of last space
last_ndx = line.rfind(' ')
# line[:23]: The time stamp (first 23 characters)
# line[last_ndx:]: Last space and following characters
out_file.write(line[:23] + line[last_ndx:]) 
Если у вас есть и другие записи журнала, которые не должны совпадать, вы все равно можете применить регулярное выражение к последней части line[last_ndx:] и проверьте,соответствует ли это (например, " IN[_A-Z]+?[0-9]+$").


py.Net.JS

Это идеальная пара... Большое вам спасибо.
Как я могу добавить регулярное выражение к последнему индексу, чтобы убедиться, что оно соответствует регулярному выражению?

Jochen Arndt

Используйте что-то вроде
matchObj = re.match(pattern, line[last_ndx:])
Если matchObj не равен null, то шаблон был найден в строке.

Обратите внимание, что функция match() проверяет начало строки (пробел). Вы также можете использовать функцию search (), где шаблон может быть расположен в любом месте строки, и/или использовать строку[last_ndx+1:], потому что вы уже знаете, что есть пробел.

py.Net.JS

Совершенно Потрясающе ....
Это идеальное решение для моего первого проекта на python.
большое спасибо дружище

Jochen Arndt

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

Одно замечание к вашему решению:
Нет никакой необходимости проверять совпадение дважды. Линия
if (line_regex.search(line)):
могут быть удалены (а также блок с повышенным уровнем).

py.Net.JS

теперь мой код возвращает следующий вывод

2017-03-18 , INBIOS_ABZ824
2017-03-19 , INBIOS_ABZ824
2017-03-12 , INDROS_MSR656
2017-03-17 , INDROS_MSR656
2017-04-12 , INHP_GSN848
2017-04-19 , INHP_GSN848

Есть несколько множественных значений с разными значениями даты, из которых я хочу извлечь только самую старую дату и исключить остальные? каким должен быть наилучший подход? не могли бы вы предложить?

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

2017-03-18 , INBIOS_ABZ824
2017-03-12 , INDROS_MSR656
2017-04-12 , INHP_GSN848

Jochen Arndt

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

py.Net.JS

Спасибо , Йохен.

Я сформировал список из выходного файла,

text_file = open("dataoutput.txt", "Р")
линии = text_file.читать().сплит('^')

как я могу извлечь самые старые даты и соответствующее им значение из этого списка ?

Jochen Arndt

Существует множество решений.

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

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

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

Рейтинг:
10

py.Net.JS

Итак вот окончательный код который дает мне идеальные результаты,

import os
import re

# Regex used to match relevant loglines (in this case, a specific IP address)
line_regex = re.compile(r"error", re.IGNORECASE)

line_regex = re.compile(r"[A-Z]+OS_[A-Z]+[0-9]+", re.IGNORECASE)


# Output file, where the matched loglines will be copied to
output_filename = os.path.normpath("output.log")
# Overwrites the file, ensure we're starting out with a blank file
with open(output_filename, "w") as out_file:
    out_file.write("")

# Open output file in 'append' mode
with open(output_filename, "a") as out_file:
    # Open input file in 'read' mode
    with open("ServerError.txt", "r") as in_file:
        # Loop over each log line
        for line in in_file:
            # If log line matches our regex, print to console, and output file
            if (line_regex.search(line)):

                # Get index of last space
                last_ndx = line.rfind(' ')
                # line[:23]: The time stamp (first 23 characters)
                # line[last_ndx:]: Last space and following characters

                # using match object to eliminate other strings which are associated with the pattern ,
                # need the string from which the request ID is in the last index
                matchObj = re.match(line_regex, line[last_ndx+1:])
                #print(matchObj)
                #check if matchobj is not null
                if matchObj:
                    print(line[:23] + line[last_ndx:])
                    out_file.write(line[:23] + line[last_ndx:])