Python grep и cut

#python #cisco

#python #cisco

Вопрос:

В Linux легко получить определенную строку с помощью таких инструментов, как grep, cut или awk.

Этот show version образец взят из https://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst9300/software/release/16-6/configuration_guide/sys_mgmt/b_166_sys_mgmt_9300_cg/b_166_sys_mgmt_9300_cg_chapter_01.html

 wolf@linux:~$ cat shver
cisco C9300-48P (X86) processor with 818597K/6147K bytes of memory.
Processor board ID FCW2049G03S
2048K bytes of non-volatile configuration memory.
8388608K bytes of physical memory.
1638400K bytes of Crash Files at crashinfo:.
11264000K bytes of Flash at flash:.
0K bytes of WebUI ODM Files at webui:.
Model Number                       : C9300-48P

Base Ethernet MAC Address          : 04:6c:9d:01:3b:80
Motherboard Assembly Number        : 73-17956-04
Motherboard Serial Number          : FOC20465ABU
Model Revision Number              : P4B
Motherboard Revision Number        : 04
Model Number                       : C9300-48P
System Serial Number               : FCW2049G03S

wolf@linux:~$ 
 

grep и вырезать

 wolf@linux:~$ grep 'Model Number' shver | cut -d : -f 2
 C9300-48P
 C9300-48P
wolf@linux:~$ 
 

Удалите лишнее пространство (если есть лучшее решение, дайте мне знать).

 wolf@linux:~$ grep 'Model Number' shver | cut -d : -f 2 | cut -d ' ' -f 2
C9300-48P
C9300-48P
wolf@linux:~$ 
 

Выберите 1-й выход

 wolf@linux:~$ grep 'Model Number' shver | cut -d : -f 2 | cut -d ' ' -f 2 | head -1
C9300-48P
wolf@linux:~$ 
 

Это было в Linux. Я планировал написать аналогичный код на Python.

Моя попытка, которая все еще не сработала на данный момент.

Определить строку shver

 >>> shver = '''cisco C9300-48P (X86) processor with 818597K/6147K bytes of memory.
... Processor board ID FCW2049G03S
... 2048K bytes of non-volatile configuration memory.
... 8388608K bytes of physical memory.
... 1638400K bytes of Crash Files at crashinfo:.
... 11264000K bytes of Flash at flash:.
... 0K bytes of WebUI ODM Files at webui:.
... Model Number                       : C9300-48P
... 
... Base Ethernet MAC Address          : 04:6c:9d:01:3b:80
... Motherboard Assembly Number        : 73-17956-04
... Motherboard Serial Number          : FOC20465ABU
... Model Revision Number              : P4B
... Motherboard Revision Number        : 04
... Model Number                       : C9300-48P
... System Serial Number               : FCW2049G03S
... '''
>>> 
 

проверьте это

 >>> shver
'cisco C9300-48P (X86) processor with 818597K/6147K bytes of memory.nProcessor board ID FCW2049G03Sn2048K bytes of non-volatile configuration memory.n8388608K bytes of physical memory.n1638400K bytes of Crash Files at crashinfo:.n11264000K bytes of Flash at flash:.n0K bytes of WebUI ODM Files at webui:.nModel Number                       : C9300-48PnnBase Ethernet MAC Address          : 04:6c:9d:01:3b:80nMotherboard Assembly Number        : 73-17956-04nMotherboard Serial Number          : FOC20465ABUnModel Revision Number              : P4BnMotherboard Revision Number        : 04nModel Number                       : C9300-48PnSystem Serial Number               : FCW2049G03Sn'
>>> 
 

создайте список

 >>> shver_list = shver.splitlines()
>>> shver_list
['cisco C9300-48P (X86) processor with 818597K/6147K bytes of memory.', 'Processor board ID FCW2049G03S', '2048K bytes of non-volatile configuration memory.', '8388608K bytes of physical memory.', '1638400K bytes of Crash Files at crashinfo:.', '11264000K bytes of Flash at flash:.', '0K bytes of WebUI ODM Files at webui:.', 'Model Number                       : C9300-48P', '', 'Base Ethernet MAC Address          : 04:6c:9d:01:3b:80', 'Motherboard Assembly Number        : 73-17956-04', 'Motherboard Serial Number          : FOC20465ABU', 'Model Revision Number              : P4B', 'Motherboard Revision Number        : 04', 'Model Number                       : C9300-48P', 'System Serial Number               : FCW2049G03S']
>>> 
 

Следующий шаг — выяснить, есть ли строка «Номер модели» или нет, и распечатать эту строку

 >>> if 'Model Number' in shver_list:
...     'yes'
... else:
...     'no'
... 
'no'
>>> 
 

Как мне распечатать строку, содержащую «Номер модели»?

 >>> for i in shver_list:
...     if 'Model Number' in shver_list:
...             i
... 
>>> 
 

Желаемый результат

 C9300-48P
 

Ответ №1:

Вы можете анализировать данные в словаре, что упрощает доступ к соответствующей информации:

 shver = '''cisco C9300-48P (X86) processor with 818597K/6147K bytes of memory.
Processor board ID FCW2049G03S
2048K bytes of non-volatile configuration memory.
8388608K bytes of physical memory.
1638400K bytes of Crash Files at crashinfo:.
11264000K bytes of Flash at flash:.
0K bytes of WebUI ODM Files at webui:.
Model Number                       : C9300-48P

Base Ethernet MAC Address          : 04:6c:9d:01:3b:80
Motherboard Assembly Number        : 73-17956-04
Motherboard Serial Number          : FOC20465ABU
Model Revision Number              : P4B
Motherboard Revision Number        : 04
Model Number                       : C9300-48P
System Serial Number               : FCW2049G03S
'''

attributes = {}

for line in shver.splitlines():
    if ':' in line:  # we just take lines that contain a colon
        item, value = line.strip().split(':', 1)  # Split at the first colon!
        attributes[item.strip()] = value.strip()  # remove all whitespaces

print(attributes['Model Number'])
print(attributes['System Serial Number'])
 

Вывод:

 C9300-48P
FCW2049G03S
 

Ответ №2:

Вы должны отфильтровать записи в вашем списке. Если вы фильтруете напрямую, вы ищете строки, которые буквально являются «номером модели».

Это приведет к печати всех строк, содержащих подстроку «Номер модели».

 modelnumbers = [line for line in shver_list if 'Model Number' in line]
print(modelnumbers)`
 

Чтобы получить желаемый результат, вы используете первый результат и удаляете все, что не нужно.

 print(modelnumbers[0].split(":")[1].strip())
 

Ответ №3:

С вашего shver_list шага вы можете сделать это:

 for item in shver_list:
    if "Model Number" in item:
        break
 

Поэтому, как только он найдет совпадение, он разорвет цикл и посмотрит, что у нас есть в item :

 >>> item
'Model Number                       : C9300-48P'
 

Теперь мы можем разделить это на : (обратите внимание на пробелы вокруг) и получить:

 >>> items.split(" : ")
['Model Number                      ', 'C9300-48P']
 

Итак, желаемый элемент находится в 1-м положении в этом списке.

В целом:

 for item in shver_list:
    if "Model Number" in item:
        break
desired = item.split(" : ")[1]
 

Другой способ сделать это с помощью регулярных выражений. На этот раз мы берем его из shver строки:

 import re
matches_gen = re.finditer(r"Model Numbers :s*(. )", shver)
desired = next(matches_gen).group(1)
 

Мы используем finditer для отложенной оценки, и поскольку нам нужно первое вхождение, мы используем его next для него и берем соответствующую группу, чтобы получить желаемый результат C9300-48P .