Python, l oop через текст, поиск блока - PullRequest
1 голос
/ 10 апреля 2020

Я пишу фрагмент кода python, чтобы заменить старый код php для поиска файлов различными командами показа с сетевого оборудования. Я записываю соответствующие значения в CSV-файл, чтобы создать лист, похожий на cmdb. Я сейчас пытаюсь go через поиск файла для определенного c текстового блока и записать его в другой временный файл. Вот фрагмент кода:

for root, dirs, _ in os.walk(cmdbDir):
for d in dirs:
    dir = os.path.join(root, d)
    # Loop through all subdirectories
    with os.scandir(dir) as it:
        for entry in it:
            if entry.name.endswith(".txt") and entry.is_file():
                if dir.endswith('juniper'):
                    manufacturer = 'Juniper'
                    flag = False
                    flag2 = False
                    with open(entry.path, 'r') as f:
                        for line in f:
                            # Write a temp file per Juniper Node
                            nodes = ['node0','node1']
                            for node in nodes:
                                tmpfile = (f'{tmpDir}\\{hostname}-{node}.txt')
                                temp_file = open(tmpfile, 'a')
                                if line.startswith(f'set groups {node}'):
                                    temp_file.write(line)

                                # Search for section show chassis hardware
                                if line.startswith('show chassis hardware'):
                                    flag = True
                                elif line.startswith('{primary:node0}'):
                                    flag = False
                                elif flag:
                                    if line.startswith(node):
                                        flag2 = True
                                    elif line.startswith('\n') or len(line) == 0:
                                        flag2 = False
                                    elif flag2:
                                        print(line)
                                        temp_file.write(line)
                                temp_file.close()

Таким образом, он проходит по директории и ищет во всех подкаталогах файл с расширением .txt. С этим конкретным устройством Juniper я бы хотел собрать данные для node0 и node1 и поместить их в отдельные файлы. Когда я запускаю этот код только для 1 узла (таким образом, я передаю только аргумент node0 или node1), он работает нормально, поэтому код grep для текста выглядит нормально. Когда я пытаюсь запустить код для node0 и node1, что-то не так с установкой флагов, я думаю, тогда я вижу вывод для узлов бота в обоих текстовых файлах.

Вот фрагмент исходного файла, который я цикл через:

show chassis hardware
node0:
--------------------------------------------------------------------------
Hardware inventory:
Item             Version  Part number  Serial number     Description
Chassis                                CV3016AF1127      SRX300
Routing Engine   REV 0x08 650-065039   CV3016AF1127      RE-SRX300
FPC 0                                                    FPC
  PIC 0                                                  6xGE,2xGE SFP Base PIC
Power Supply 0

node1:
--------------------------------------------------------------------------
Hardware inventory:
Item             Version  Part number  Serial number     Description
Chassis                                CV3016AF1125      SRX300
Routing Engine   REV 0x08 650-065039   CV3016AF1125      RE-SRX300
FPC 0                                                    FPC
  PIC 0                                                  6xGE,2xGE SFP Base PIC
Power Supply 0

{primary:node0}

Таким образом, он сначала ищет текст между «show chassis hardware» и {primary: node0}, а затем ищет текст между «node0» и пустой строкой, и примерно так же для node1

Это результат при запуске этого кода только с node0:

set groups node0 system host-name xxx
set groups node0 interfaces fxp0 unit 0 family inet address x.x.x.x/26
set groups node0 interfaces fxp0 unit 0 family inet address x.x.x.x/26 master-only
--------------------------------------------------------------------------
Hardware inventory:
Item             Version  Part number  Serial number     Description
Chassis                                CV3016AF1127      SRX300
Routing Engine   REV 0x08 650-065039   CV3016AF1127      RE-SRX300
FPC 0                                                    FPC
  PIC 0                                                  6xGE,2xGE SFP Base PIC
Power Supply 0

И когда я запускаю его с node0, node1:

set groups node1 system host-name xxx
set groups node1 interfaces fxp0 unit 0 family inet address x.x.x.x/26
set groups node1 interfaces fxp0 unit 0 family inet address x.x.x.x/26 master-only
node0:
--------------------------------------------------------------------------
Hardware inventory:
Item             Version  Part number  Serial number     Description
Chassis                                CV3016AF1127      SRX300
Routing Engine   REV 0x08 650-065039   CV3016AF1127      RE-SRX300
FPC 0                                                    FPC
  PIC 0                                                  6xGE,2xGE SFP Base PIC
Power Supply 0
--------------------------------------------------------------------------
Hardware inventory:
Item             Version  Part number  Serial number     Description
Chassis                                CV3016AF1125      SRX300
Routing Engine   REV 0x08 650-065039   CV3016AF1125      RE-SRX300
FPC 0                                                    FPC
  PIC 0                                                  6xGE,2xGE SFP Base PIC
Power Supply 0

Я пытаюсь Я понимаю, что в l oop что-то идет не так, я думаю, что в l *1026* что-то не так, что определенная переменная не сбрасывается или остается "активной"

Я также пытался поместить фрагмент кода в функция, но это дало тот же результат.

Заранее спасибо.

1 Ответ

0 голосов
/ 12 апреля 2020

flag2 должен быть установлен для каждого узла отдельно. Для этого переместите линию nodes = ['node0','node1'] вверх над начальной flag2 = False. Затем замените последнюю строку на flag2 = dict.fromkeys(nodes, False) и каждое последующее использование flag2 на flag2[node].

Тогда соответствующая часть кода выглядит (не проверено):

        if dir.endswith('juniper'):
            manufacturer = 'Juniper'
            nodes = ['node0','node1']
            flag = False
            flag2 = dict.fromkeys(nodes, False)
            with open(entry.path, 'r') as f:
                for line in f:
                    # Write a temp file per Juniper Node
                    for node in nodes:
                        tmpfile = (f'{tmpDir}\\{hostname}-{node}.txt')
                        temp_file = open(tmpfile, 'a')
                        if line.startswith(f'set groups {node}'):
                            temp_file.write(line)

                        # Search for section show chassis hardware
                        if line.startswith('show chassis hardware'):
                            flag = True
                        elif line.startswith('{primary:node0}'):
                            flag = False
                        elif flag:
                            if line.startswith(node):
                                flag2[node] = True
                            elif line.startswith('\n') or len(line) == 0:
                                flag2[node] = False
                            elif flag2[node]:
                                print(line)
                                temp_file.write(line)
                        temp_file.close()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...