Contents Menu Expand Light mode Dark mode Auto light/dark mode
Python для сетевых инженеров
Python для сетевых инженеров
  • Введение
    • О книге
    • Часто задаваемые вопросы (FAQ)
    • Благодарности
  • I. Основы Python
    • 1. Подготовка к работе
      • Подготовка рабочего окружения
      • ОС и редактор
      • Система управления пакетами pip
      • Виртуальные окружения
      • Интерпретатор Python
      • Дополнительные материалы
      • Задания
    • 2. Использование Git и GitHub
      • Основы Git
      • Отображение статуса репозитория в приглашении
      • Работа с Git
      • Дополнительные возможности
      • Аутентификация на GitHub
      • Работа со своим репозиторием заданий
      • Работа с репозиторием заданий и примеров
      • Дополнительные материалы
      • Задания
    • 3. Начало работы с Python
      • Синтаксис Python
      • Интерпретатор Python. IPython
      • Специальные команды ipython
      • Переменные
      • Задания
    • 4. Типы данных в Python
      • Числа
      • Строки (Strings)
        • Полезные методы для работы со строками
        • Форматирование строк
        • Объединение литералов строк
      • Список (List)
        • Полезные методы для работы со списками
      • Словарь (Dictionary)
        • Полезные методы для работы со словарями
        • Варианты создания словаря
      • Кортеж (Tuple)
      • Множество (Set)
        • Полезные методы для работы с множествами
        • Операции с множествами
        • Варианты создания множества
      • Булевы значения
      • Преобразование типов
      • Проверка типов
      • Вызов методов цепочкой
      • Основы сортировки данных
      • Дополнительные материалы
      • Задания
    • 5. Создание базовых скриптов
      • Исполняемый файл
      • Передача аргументов скрипту (argv)
      • Ввод информации пользователем
      • Задания
    • 6. Контроль хода программы
      • if/elif/else
      • for
        • Вложенные for
        • Совмещение for и if
      • while
      • break, continue, pass
      • for/else, while/else
      • Работа с исключениями try/except/else/finally
      • Дополнительные материалы
      • Задания
    • 7. Работа с файлами
      • Открытие файлов
      • Чтение файлов
      • Запись файлов
      • Закрытие файлов
      • Конструкция with
      • Примеры работы с файлами
      • Дополнительные материалы
      • Задания
    • 8. Полезные возможности и инструменты
      • Форматирование строк с помощью f-строк
      • Распаковка переменных
      • List, dict, set comprehensions
      • Отладка кода
      • Дополнительные материалы
  • II. Повторное использование кода
    • 9. Функции
      • Создание функций
      • Пространства имен. Области видимости
      • Параметры и аргументы функций
        • Типы параметров функции
        • Типы аргументов функции
        • Аргументы переменной длины
        • Распаковка аргументов
        • Пример использования ключевых аргументов переменной длины и распаковки аргументов
      • Аргументы, которые можно передавать только как ключевые
      • Распространенные проблемы/нюансы работы с функциями
      • Дополнительные материалы
      • Задания
    • 10. Полезные функции
      • Функция print
      • Функция range
      • Функция sorted
      • enumerate
      • Функция zip
      • Функция all
      • Функция any
      • Анонимная функция (лямбда-выражение)
      • Функция map
      • Функция filter
    • 11. Модули
      • Импорт модуля
      • Создание своих модулей
      • if __name__ == "__main__"
      • Пути поиска модулей
      • Рекомендации по поводу расположения функций в коде
      • Задания
    • 12. Полезные модули
      • Модуль subprocess
      • Модуль os
      • Модуль ipaddress
      • Модуль tabulate
      • Модуль pprint
      • Дополнительные материалы
      • Задания
    • 13. Итераторы, итерируемые объекты и генераторы
      • Итерируемый объект
      • Итераторы
      • Генератор (generator)
      • Дополнительные материалы
  • III. Регулярные выражения
    • 14. Синтаксис регулярных выражений
      • Синтаксис регулярных выражений
      • Наборы символов
      • Символы повторения
      • Специальные символы
      • Жадность символов повторения
      • Группировка выражений
      • Разбор вывода команды show ip dhcp snooping с помощью именованных групп
      • Группа без захвата
      • Повторение захваченного результата
      • Дополнительные материалы
    • 15. Модуль re
      • Объект Match
      • Функция search
      • Функция match
      • Функция finditer
      • Функция findall
      • Функция compile
      • Флаги
      • Функция re.split
      • Функция re.sub
      • Дополнительные материалы
      • Задания
  • IV. Запись и передача данных
    • 16. Unicode
      • Стандарт Юникод
      • Юникод в Python 3
      • Конвертация между байтами и строками
      • Примеры конвертации между байтами и строками
      • Ошибки при конвертации
      • Дополнительные материалы
    • 17. Работа с файлами в формате CSV, JSON, YAML
      • Работа с файлами в формате CSV
      • Работа с файлами в формате JSON
      • Работа с файлами в формате YAML
      • Дополнительные материалы
      • Задания
  • V. Работа с сетевым оборудованием
    • 18. Подключение к оборудованию
      • Ввод пароля
      • Модуль pexpect
      • Модуль telnetlib
      • Модуль paramiko
      • Модуль netmiko
      • Модуль scrapli
      • Дополнительные материалы
      • Задания
    • 19. Одновременное подключение к нескольким устройствам
      • Измерение времени выполнения скрипта
      • Процессы и потоки в Python (CPython)
      • Количество потоков
      • Потоковая безопасность
      • Модуль logging
      • Модуль concurrent.futures
        • Метод map
        • Метод submit и работа с futures
      • Дополнительные материалы
      • Задания
    • 20. Шаблоны конфигураций с Jinja2
      • Начало работы с Jinja2
      • Пример использования Jinja
      • Синтаксис шаблонов Jinja2
        • Контроль символов whitespace
        • Переменные
        • Цикл for
        • if/elif/else
        • Фильтры
        • Тесты
        • set
        • include
      • Наследование шаблонов
      • Дополнительные материалы
      • Задания
    • 21. Обработка вывода команд TextFSM
      • Начало работы с TextFSM
      • Синтаксис шаблонов TextFSM
      • Правила состояний
      • Примеры использования TextFSM
      • TextFSM CLI Table
      • Дополнительные материалы
      • Задания
  • VI. Основы объектно-ориентированного программирования
    • 22. Основы ООП
      • Основы ООП
      • Создание класса
      • Создание метода
      • Параметр self
      • Метод __init__
      • Пример класса
      • Область видимости
      • Переменные класса
      • Задания
    • 23. Специальные методы
      • Подчеркивание в именах
      • Методы __str__, __repr__
      • Поддержка арифметических операторов
      • Протоколы
        • Протокол итерации
        • Протокол последовательности
        • Менеджер контекста
      • Дополнительные материалы
      • Задания
    • 24. Наследование
      • Основы наследования
      • Задания
  • VII. Работа с базами данных
    • 25. Работа с базами данных
      • SQL
      • SQLite
      • Основы SQL (в sqlite3 CLI)
        • CREATE
        • DROP
        • INSERT
        • SELECT
        • WHERE
        • ALTER
        • UPDATE
        • REPLACE
        • DELETE
        • ORDER BY
        • AND
        • OR
        • IN
        • NOT
      • Модуль sqlite3
        • Выполнение команд SQL
        • Получение результатов запроса
        • Cursor как итератор
        • Использование модуля sqlite3 без явного создания курсора
        • Обработка исключений
        • Connection как менеджер контекста
        • Пример использования SQLite
      • Дополнительные материалы
      • Задания
  • VIII. Дополнительная информация
    • Модуль argparse
    • Форматирование строк с оператором %
    • Соглашение об именах
    • Подчеркивание в именах
    • Отличия Python 2.7 и Python 3.6
    • Проверка заданий с помощью утилиты pyneng
    • Проверка заданий с помощью pytest
      • Основы pytest
      • Особенности использования pytest для проверки заданий
      • pytest-clarity
  • Продолжение обучения
  • Скачать PDF/Epub

Ресурсы

  • Задания, примеры кода
  • Лекции по Python для сетевых инженеров

Languages

  • Ukrainian
  • English
Back to top

Функция search#

Функция search:

  • используется для поиска подстроки, которая соответствует шаблону

  • возвращает объект Match, если подстрока найдена

  • возвращает None, если подстрока не найдена

Функция search подходит в том случае, когда надо найти только одно совпадение в строке, например, когда регулярное выражение описывает всю строку или часть строки.

Рассмотрим пример использования функции search в разборе лог-файла.

В файле log.txt находятся лог-сообщения с информацией о том, что один и тот же MAC слишком быстро переучивается то на одном, то на другом интерфейсе. Одна из причин таких сообщений - петля в сети.

Содержимое файла log.txt:

%SW_MATM-4-MACFLAP_NOTIF: Host 01e2.4c18.0156 in vlan 10 is flapping between port Gi0/16 and port Gi0/24
%SW_MATM-4-MACFLAP_NOTIF: Host 01e2.4c18.0156 in vlan 10 is flapping between port Gi0/16 and port Gi0/24
%SW_MATM-4-MACFLAP_NOTIF: Host 01e2.4c18.0156 in vlan 10 is flapping between port Gi0/24 and port Gi0/19
%SW_MATM-4-MACFLAP_NOTIF: Host 01e2.4c18.0156 in vlan 10 is flapping between port Gi0/24 and port Gi0/16

При этом MAC-адрес может прыгать между несколькими портами. В таком случае очень важно знать, с каких портов прилетает MAC.

Попробуем вычислить, между какими портами и в каком VLAN образовалась проблема. Проверка регулярного выражения с одной строкой из log-файла:

In [1]: import re

In [2]: log = '%SW_MATM-4-MACFLAP_NOTIF: Host 01e2.4c18.0156 in vlan 10 is flapping between port Gi0/16 and port Gi0/24'

In [3]: match = re.search(r'Host \S+ '
   ...:                   r'in vlan (\d+) '
   ...:                   r'is flapping between port '
   ...:                   r'(\S+) and port (\S+)', log)
   ...:

Регулярное выражение для удобства чтения разбито на части. В нём есть три группы:

  • (\d+) - описывает номер VLAN

  • (\S+) and port (\S+) - в это выражение попадают номера портов

В итоге, в группы попали такие части строки:

In [4]: match.groups()
Out[4]: ('10', 'Gi0/16', 'Gi0/24')

В итоговом скрипте файл log.txt обрабатывается построчно, и из каждой строки собирается информация о портах. Так как порты могут дублироваться, сразу добавляем их в множество, чтобы получить подборку уникальных интерфейсов (файл parse_log_search.py):

import re

regex = (r'Host \S+ '
         r'in vlan (\d+) '
         r'is flapping between port '
         r'(\S+) and port (\S+)')

ports = set()

with open('log.txt') as f:
    for line in f:
        match = re.search(regex, line)
        if match:
            vlan = match.group(1)
            ports.add(match.group(2))
            ports.add(match.group(3))

print('Петля между портами {} в VLAN {}'.format(', '.join(ports), vlan))

Результат выполнения скрипта такой:

$ python parse_log_search.py
Петля между портами Gi0/19, Gi0/24, Gi0/16 в VLAN 10

Обработка вывода show cdp neighbors detail#

Попробуем получить параметры устройств из вывода sh cdp neighbors detail.

Пример вывода информации для одного соседа:

SW1#show cdp neighbors detail
-------------------------
Device ID: SW2
Entry address(es):
  IP address: 10.1.1.2
Platform: cisco WS-C2960-8TC-L,  Capabilities: Switch IGMP
Interface: GigabitEthernet1/0/16,  Port ID (outgoing port): GigabitEthernet0/1
Holdtime : 164 sec

Version :
Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 12.2(55)SE9, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2014 by Cisco Systems, Inc.
Compiled Mon 03-Mar-14 22:53 by prod_rel_team

advertisement version: 2
VTP Management Domain: ''
Native VLAN: 1
Duplex: full
Management address(es):
  IP address: 10.1.1.2

Задача получить такие поля:

  • имя соседа (Device ID: SW2)

  • IP-адрес соседа (IP address: 10.1.1.2)

  • платформу соседа (Platform: cisco WS-C2960-8TC-L)

  • версию IOS (Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 12.2(55)SE9, RELEASE SOFTWARE (fc1))

И для удобства надо получить данные в виде словаря. Пример итогового словаря для коммутатора SW2:

{'SW2': {'ip': '10.1.1.2',
         'platform': 'cisco WS-C2960-8TC-L',
         'ios': 'C2960 Software (C2960-LANBASEK9-M), Version 12.2(55)SE9'}}

Пример проверяется на файле sh_cdp_neighbors_sw1.txt.

Первый вариант решения (файл parse_sh_cdp_neighbors_detail_ver1.py):

import re
from pprint import pprint


def parse_cdp(filename):
    result = {}

    with open(filename) as f:
        for line in f:
            if line.startswith('Device ID'):
                neighbor = re.search(r'Device ID: (\S+)', line).group(1)
                result[neighbor] = {}
            elif line.startswith('  IP address'):
                ip = re.search(r'IP address: (\S+)', line).group(1)
                result[neighbor]['ip'] = ip
            elif line.startswith('Platform'):
                platform = re.search(r'Platform: (\S+ \S+),', line).group(1)
                result[neighbor]['platform'] = platform
            elif line.startswith('Cisco IOS Software'):
                ios = re.search(r'Cisco IOS Software, (.+), RELEASE',
                                line).group(1)
                result[neighbor]['ios'] = ios

    return result


pprint(parse_cdp('sh_cdp_neighbors_sw1.txt'))

Тут нужные строки отбираются с помощью метода строк startswith. И в строке с помощью регулярного выражения получается требуемая часть строки. В итоге все собирается в словарь.

Результат выглядит так:

$ python parse_sh_cdp_neighbors_detail_ver1.py
{'R1': {'ios': '3800 Software (C3825-ADVENTERPRISEK9-M), Version 12.4(24)T1',
        'ip': '10.1.1.1',
        'platform': 'Cisco 3825'},
 'R2': {'ios': '2900 Software (C3825-ADVENTERPRISEK9-M), Version 15.2(2)T1',
        'ip': '10.2.2.2',
        'platform': 'Cisco 2911'},
 'SW2': {'ios': 'C2960 Software (C2960-LANBASEK9-M), Version 12.2(55)SE9',
         'ip': '10.1.1.2',
         'platform': 'cisco WS-C2960-8TC-L'}}

Все получилось как нужно, но эту задачу можно решить более компактно.

Вторая версия решения (файл parse_sh_cdp_neighbors_detail_ver2.py):

import re
from pprint import pprint


def parse_cdp(filename):
    regex = (r'Device ID: (?P<device>\S+)'
             r'|IP address: (?P<ip>\S+)'
             r'|Platform: (?P<platform>\S+ \S+),'
             r'|Cisco IOS Software, (?P<ios>.+), RELEASE')

    result = {}

    with open(filename) as f:
        for line in f:
            match = re.search(regex, line)
            if match:
                if match.lastgroup == 'device':
                    device = match.group(match.lastgroup)
                    result[device] = {}
                else:
                    result[device][match.lastgroup] = match.group(
                        match.lastgroup)

    return result


pprint(parse_cdp('sh_cdp_neighbors_sw1.txt'))

Пояснения ко второму варианту:

  • в регулярном выражении описаны все варианты строк через знак или |

  • без проверки строки ищется совпадение

  • если совпадение найдено, проверяется метод lastgroup

  • метод lastgroup возвращает имя последней именованной группы в регулярном выражении, для которой было найдено совпадение

  • если было найдено совпадение для группы device, в переменную device записывается значение, которое попало в эту группу

  • иначе в словарь записывается соответствие „имя группы“: соответствующее значение

Результат будет таким же:

$ python parse_sh_cdp_neighbors_detail_ver2.py
{'R1': {'ios': '3800 Software (C3825-ADVENTERPRISEK9-M), Version 12.4(24)T1',
        'ip': '10.1.1.1',
        'platform': 'Cisco 3825'},
 'R2': {'ios': '2900 Software (C3825-ADVENTERPRISEK9-M), Version 15.2(2)T1',
        'ip': '10.2.2.2',
        'platform': 'Cisco 2911'},
 'SW2': {'ios': 'C2960 Software (C2960-LANBASEK9-M), Version 12.2(55)SE9',
         'ip': '10.1.1.2',
         'platform': 'cisco WS-C2960-8TC-L'}}
Next
Функция match
Previous
Объект Match
Copyright © 2015-2022, Natasha Samoylenko
Made with Sphinx and @pradyunsg's Furo
Last updated on мая 31, 2023
Содержание
  • Функция search
    • Обработка вывода show cdp neighbors detail