Разбор определенных строк из элементов списка в python

У меня есть следующий код на python, который содержит сообщения журнала для отладки SSH.

for log_item in ssh_log:
   print(log_item.rstrip())

#will show ...
2022-04-06 01:55:15,085 10.x Remote version/idstring: SSH-2.0-ConfD-4.3.11.4
2022-04-06 01:55:15,085 20.x Connected (version 2.0, client ConfD-4.3.11.4)
2022-04-06 01:55:15,161 10.x kex algos:['diffie-hellman-group14-sha1'] server key:['ssh-rsa']
...

Каков подход, чтобы получить значения, выделенные жирным шрифтом, назначить мои переменные, возможно, какое-то регулярное выражение как часть цикла for или что-то еще, чтобы получить следующее:

idstring = SSH-2.0-ConfD-4.3.11.4
kex_algos = ['diffie-hellman-group14-sha1']
key_type = ['ssh-rsa']

регулярное выражение может не понадобиться для такого простого случая. Вы можете просто использовать log_item.find(), чтобы отфильтровать соответствующие строки, затем log_item.split(), чтобы разделить их на строки и выбрать интересные по индексу.

Jussi Nurminen 06.04.2022 08:26

Все ли строки в файле журнала содержат один из «Remote», «Connected» или «kex»? Предложенные до сих пор ответы могут работать для этого подмножества данных журнала, но что, если этих токенов нет в файле? Кроме того, почему вам нужны kex_algos и key_type в виде списков?

Lancelot du Lac 06.04.2022 09:02

Привет, да, все линии будут иметь эти элементы. На самом деле мне не нужны kex_algos или key_type в виде списков, просто их вывод в журнале такой

JON 06.04.2022 19:24
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
62
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Если все данные имеют тот же формат, что и данные, приведенные здесь, вы можете использовать следующее регулярное выражение:

import re
a = """
2022-04-06 01:55:15,085 10.x Remote version/idstring: SSH-2.0-ConfD-4.3.11.4
2022-04-06 01:55:15,085 20.x Connected (version 2.0, client ConfD-4.3.11.4)
2022-04-06 01:55:15,161 10.x kex algos:['diffie-hellman-group14-sha1'] server key:['ssh-rsa']"""

idstring = re.findall("idstring: (.*)", a)[0] # Remove zero to get a list if 
                                              # multiple values are present
print(idstring)
kex_algos = re.findall("algos:\['(.*)'\] ", a)
print(kex_algos)
key_type = re.findall("key:\['(.*)'\]", a)
print(key_type)

Выход:

'SSH-2.0-ConfD-4.3.11.4'
['diffie-hellman-group14-sha1']
['ssh-rsa']
Ответ принят как подходящий

Решение без регулярного выражения. См. встроенные комментарии ниже.

for log_item in ssh_log:
    line = log_item.rstrip()
    if 'idstring' in line:
        print('idstring = ',line.split(':')[-1]) #Pick last value after ':'
    if 'kex algos' in line:
        print('kex algos = ', line[line.find('['):line.find(']')+1]) #find between first set of square brackets.
    if 'key:' in line:
        key = line.split('key:')[1] #Get values after 'key:'
        print('key_type = ', key)

Вы можете обновить отпечатки для присвоения переменных, если это то, что вам нужно.

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

from ttp import ttp
import json

with open("log.txt") as f:
    data_to_parse = f.read()

ttp_template = """
{{ignore}} {{ignore}} {{ignore}} {{ignore}} version/idstring: {{version_id_string}}
{{ignore}} {{ignore}} {{ignore}} {{ignore}} algos:{{key_algos}} server key:{{key_type}}
"""

parser = ttp(data=data_to_parse, template=ttp_template)
parser.parse()

# print result in JSON format
results = parser.result(format='json')[0]
# print(results)

result = json.loads(results)

# print(result)

for i in result:
    print(i["key_algos"])
    print(i["key_type"])
    print(i["version_id_string"])

Результат:

['diffie-hellman-group14-sha1']
['ssh-rsa']
SSH-2.0-ConfD-4.3.11.4

Имея 3 строки образца данных из исходного вопроса в файле, можно было бы использовать этот подход:

import re

with open('ssh.log') as sshlog:
    for line in map(str.strip, sshlog):
        _, _, _, kw, *rem = line.split()
        match kw:
            case 'Remote':
                print(f'ID string = {rem[-1]}')
            case 'kex':
                m = re.findall("(?<=\[').+?(?='\])", line)
                print(f'algos = {m[0]}')
                print(f'type = {m[1]}')
            case _:
                pass

Здесь предполагается, что интерес представляют только строки с одним из ключевых слов «Remote» или «kex».

Выход:

ID string = SSH-2.0-ConfD-4.3.11.4
algos = diffie-hellman-group14-sha1
type = ssh-rsa

Другие вопросы по теме