Разберите пользовательский файл журнала в словарь с помощью регулярного выражения - PullRequest
2 голосов
/ 09 мая 2020

Образец файла журнала

Jun 15 02:04:59 combo sshd(pam_unix)[20897]: authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=220-135-151-1.hinet-ip.hinet.net  user=root\n'
Jun 15 02:04:59 combo sshd(pam_unix)[20898]: authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=220-135-151-1.hinet-ip.hinet.net  user=root\n'
Jun 15 04:06:18 combo su(pam_unix)[21416]: session opened for user cyrus by (uid=0)\n'
Jun 15 04:06:19 combo su(pam_unix)[21416]: session closed for user cyrus\n'
Jun 15 04:06:20 combo logrotate: ALERT exited abnormally with [1]\n'
Jun 15 04:12:42 combo su(pam_unix)[22644]: session opened for user news by (uid=0)\n'
Jun 15 04:12:43 combo su(pam_unix)[22644]: session closed for user news\n'

Я хочу разделить данные на 4 столбца: Дата, Время, PID и Сообщение.

Пример вывода будет

Dict = {"Date": "Jun 15", "Time": "02:04:59", "PID": "20897", "Message": "authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=220-135-151-1.hinet-ip.hinet.net  user=root\n'"}

После чего я собираюсь сохранить эту информацию в CSV-файл на основе столбцов

Я пробовал посмотреть другие примеры, такие как:

Разобрать пользовательский файл журнала в python

Как разобрать этот пользовательский файл журнала в Python

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

Текущее регулярное выражение, которое у меня есть:

"(\ w {3} \ d {2})" для даты

"(\ d {2} : \ d {2}: \ d {2}) "для времени

" (? <= [). +? (? =] :) "для PID </p>

" (( ? <=:). *) "для сообщения </p>

, но ничего не происходит, когда я объединяю их вместе

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Решение - перебирать каждую строку. Для каждой строки выберите Date, Time, PID и Message с помощью специального c регулярного выражения.

Если они найдены, верните значение. В противном случае верните None.

Вот код:

# Import module
import re

# Output list
out = []
# Read file
with open("data.txt", "r") as f:
    # Iterate over all lines
    for line in f.readlines():
        # Select the different fields
        date = re.search(r'^(\w{3}\s\d{2})', line)
        time = re.search(r'(\d{2}:\d{2}:\d{2})', line)
        PID = re.search(r'\[([0-9]+)\]:', line)
        message = re.search(r":\s(.*?)$", line)
        # Append them to the output using a dict
        # If field isn't found, None is return
        out.append({
            "Date": date.group(1) if date else None,
            "Time": time.group(1) if time else None,
            "PID": PID.group(1) if PID else None,
            "Message": message.group(1) if message else None
        })

вывод :

# [
#     {'Date': 'Jun 15', 'Time': '02:04:59', 'PID': '20897', 'Message': "authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=220-135-151-1.hinet-ip.hinet.net  user=root\\n'"},
#     {'Date': 'Jun 15', 'Time': '02:04:59', 'PID': '20898', 'Message': "authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=220-135-151-1.hinet-ip.hinet.net  user=root\\n'"},
#     {'Date': 'Jun 15', 'Time': '04:06:18', 'PID': '21416', 'Message': "session opened for user cyrus by (uid=0)\\n'"},
#     {'Date': 'Jun 15', 'Time': '04:06:19', 'PID': '21416', 'Message': "session closed for user cyrus\\n'"},
#     {'Date': 'Jun 15', 'Time': '04:06:20', 'PID': None, 'Message': "ALERT exited abnormally with [1]\\n'"},
#     {'Date': 'Jun 15', 'Time': '04:12:42', 'PID': '22644', 'Message': "session opened for user news by (uid=0)\\n'"},
#     {'Date': 'Jun 15', 'Time': '04:12:43', 'PID': '22644', 'Message': 'session closed for user news\\n'}
# ]

Надеюсь, что это поможет!

0 голосов
/ 09 мая 2020

Что значит объединить их вместе? Вы пробовали делать это за l oop? Вероятно, я бы сделал это go таким же образом. Похоже, вы пытаетесь захватить все группы и передать их re.findall (я предполагаю). Но findall используется для захвата нескольких экземпляров одной группы захвата. Следовательно, поместите свое регулярное выражение в список, выполните итерацию и сопоставьте каждое из них, используя метод re.find или captures. Регулярное выражение, которое у вас есть, верное (хотя для даты я бы записал первые два слова каждой строки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...