Разделить список по ключевому слову, которое может появляться несколько раз - PullRequest
0 голосов
/ 23 октября 2018

Я читал примеры, которые кажутся похожими, но я не на том уровне, чтобы понять ответы.Я хочу взять вывод списка и написать каждый интерфейс отдельной строкой (aka list I write to a csv).Мне нужно разделить начальный список возврата по ключевому слову 'interface Vlan *'

Я хочу разбить возвращенный список vlanlist по интерфейсу ключевых слов vlan* на отдельные списки

from ciscoconfparse import CiscoConfParse
import os

for filename in os.listdir():
    if filename.endswith(".cfg"):
        p = CiscoConfParse(filename)
        vlanlist=(p.find_all_children('^interface Vlan'))
        vlanlist.insert(0,filename)

        print(vlanlist) 

Это одинлиния вывода.Мне нужно разделить список по ключевому слову "interface vlanxxx" на отдельные строки

[ 'interface Vlan1', ' no ip address', ' shutdown', 'interface Vlan2003', ' description XXXXXX', ' ip address 10.224.6.130 255.255.255.224', ' no ip redirects', ' no ip unreachables', ' no ip proxy-arp', ' load-interval 60', ' arp timeout 420']

Желаемый выход (это может иметь 2-20 различных интерфейсов, на которые я хочу разделить в зависимости от конфигурационного файла)

['interface Vlan1' ' no ip address', ' shutdown']
['interface Vlan2003', ' description XXXXXX', ' ip address 10.224.6.130 255.255.255.224', ' no ip redirects', ' no ip unreachables', ' no ip proxy-arp', ' load-interval 60', ' arp timeout 420']

Ответы [ 4 ]

0 голосов
/ 23 октября 2018

Быстрое и простое решение.Проверьте список на interface Vlan пунктов, если это так, он создает новый список, в противном случае добавляется в старый список и некоторые .strip() для хорошей меры.

output = ['interface Vlan1', ' no ip address', ' shutdown', 'interface Vlan2003', ' description XXXXXX', ' ip address 10.224.6.130 255.255.255.224', ' no ip redirects', ' no ip unreachables', ' no ip proxy-arp', ' load-interval 60', ' arp timeout 420']

results = []

for i in output:
    if 'interface Vlan' in i:
        results.append([i.strip()])
    else:
        results[-1].append(i.strip())

>> results
 [['interface Vlan1', 'no ip address', 'shutdown'],
 ['interface Vlan2003',
  'description XXXXXX',
  'ip address 10.224.6.130 255.255.255.224',
  'no ip redirects',
  'no ip unreachables',
  'no ip proxy-arp',
  'load-interval 60',
  'arp timeout 420']]
0 голосов
/ 23 октября 2018

Это идентифицирует одну точку разделения и делит ваш список на два списка, как указано.Список split_pos найдет все позиции разделения;Вы можете повторить это, если есть несколько точек разделения.Условие разделения ищет строку, начинающуюся с заданного текста и, как минимум, еще трех символов - «xxx» в вашем сообщении.

vlanlist = ['sw01.cfg', 'interface Vlan1', ' no ip address', ' shutdown', 'interface Vlan2003', ' description XXXXXX', ' ip address 10.224.6.130 255.255.255.224', ' no ip redirects', ' no ip unreachables', ' no ip proxy-arp', ' load-interval 60', ' arp timeout 420']
target = "interface Vlan"

split_pos = [idx for idx, str in enumerate(vlanlist) if str.startswith(target) and \
                                                        len(str) >= len(target)+3][0]

out1 = [vlanlist[0]] + vlanlist[1:split_pos]
out2 = [vlanlist[0]] + vlanlist[split_pos:]

print(out1)
print(out2)

Вывод:

['sw01.cfg', 'interface Vlan1', ' no ip address', ' shutdown']
['sw01.cfg', 'interface Vlan2003', ' description XXXXXX', 
 ' ip address 10.224.6.130 255.255.255.224', ' no ip redirects',
 ' no ip unreachables', ' no ip proxy-arp', ' load-interval 60', ' arp timeout 420']
0 голосов
/ 23 октября 2018

Вы можете дополнительно отделить свои возвращенные vlanlist перед добавлением имен файлов:

# First, find the index in the list where "interface Vlan" exists:
# Also, append None at the end to signify index for end of list
indices = [i for i, v in enumerate(l) if v.startswith('interface Vlan')] + [None]

# [0, 3, None]

# Then, create the list of lists based on the extracted indices and prepend with filename
newlist = [[filename] + vlanlist[indices[i]:indices[i+1]] for i in range(len(indices)-1)]

for l in newlist: print(l)

# ['test.cfg', 'interface Vlan1', ' no ip address', ' shutdown']
# ['test.cfg', 'interface Vlan2003', ' description XXXXXX', ' ip address 10.224.6.130 255.255.255.224', ' no ip redirects', ' no ip unreachables', ' no ip proxy-arp', ' load-interval 60', ' arp timeout 420']

Пояснение для второго списка понимания:

newlist = [
    [filename] +                   # prepend single-item list of filename
    vlanlist[                      # slice vlanlist
        indices[i]:                # starting at the current index
        indices[i+1]               # up to the next index
    ] 
    for i in range(len(indices)-1) # iterate up to the second last index so i+1 doesn't become IndexError
]

Если вам не нравитсяиндексный подход, вы можете попробовать zip вместо:

lists = [[filename] + vlanlist[start:end] for start, end in zip(indices[:-1], indices[1:])]
0 голосов
/ 23 октября 2018

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

def extract(items):
  result, filename, idx = [], items[0], -1

  for x in items[1:]:
    if x.startswith('interface Vlan'):
      idx += 1
      result.append([filename])
    result[idx].append(x)

  return result

# given & expected are your example and output 
assert expected == extract(given)

РЕДАКТИРОВАТЬ:
... и вы уже изменили входы ивыходы.

def extract(items):
  result, idx = [], -1

  for x in items:
    if x.startswith('interface Vlan'):
      idx += 1
      result.append([])

    if not result: continue  # assuming possible unwanted items before 'interface Vlan'
    result[idx].append(x)

  return result

assert expected == extract(given)
...