用Python解析Cisco输出
我试图解释开关的以下输出。基本上,我希望它遍历输出,直到找到“notconnect”,然后将接口的名称存储在数组中。然后继续浏览文件,并将下一个“notconnect”接口存储为数组中的下一个元素。下面示例中的接口将是Gi1/0/4。我只是不确定从哪里开始。任何帮助都将不胜感激。我正在使用Python 3.3.2用Python解析Cisco输出,python,Python,我试图解释开关的以下输出。基本上,我希望它遍历输出,直到找到“notconnect”,然后将接口的名称存储在数组中。然后继续浏览文件,并将下一个“notconnect”接口存储为数组中的下一个元素。下面示例中的接口将是Gi1/0/4。我只是不确定从哪里开始。任何帮助都将不胜感激。我正在使用Python 3.3.2 b'\r\n\r\nMS-2673-DC-CS01#terminal length 0\r\nMS-2673-DC-CS01#sh interface status\r\n\r\nPo
b'\r\n\r\nMS-2673-DC-CS01#terminal length 0\r\nMS-2673-DC-CS01#sh interface status\r\n\r\nPort Name Status Vlan Duplex Speed Type\r\nGi1/0/1 Connection to MS-2 connected trunk a-full a-1000 1000BaseSX SFP\r\nGi1/0/2 Connection to MS-2 connected trunk a-full a-1000 1000BaseSX SFP\r\nGi1/0/3 Connection to MS-2 connected trunk a-full a-1000 1000BaseSX SFP\r\nGi1/0/4 notconnect trunk auto auto Not Present\r\nGi1/0/5 Connection to MS-2 connected trunk a-full a-1000 1000BaseSX SFP\r\nGi1/0/6 Connection to MS-2 connected trunk a-full a-1000 10/100/1000BaseTX SFP\r\nGi1/0/7 Connection to MS-2 connected trunk a-full a-1000 10/100/1000BaseTX SFP\r\nGi1/0/8 Connection to MS-2 connected trunk a-full a-1000 10/100/1000BaseTX SFP\r\nGi1/0/9 Connection to MS-2 connected trunk a-full a-1000 10/100/1000BaseTX SFP\r\nGi1/0/10 Connection to MS-2 connected trunk a-full a-1000 10/100/1000BaseTX SFP\r\nGi1/0/11 Connection to MS-2 connected trunk a-full a-1000 10/100/1000BaseTX SFP\r\nGi1/0/12 Connection Server connected 32 a-full a-1000 10/100/1000BaseTX SFP\r\nMS-2673-DC-CS01#exit\r\n'
首先,您必须弄清楚格式是什么。然后您可以编写代码来解析它 显然,这是一种固定宽度的列格式。接口总是在前10个字符中,连接字符串在后20个字符中,等等。因此,给定一行:
components = (line[:10], line[10:29], line[29:42], line[42:53], line[53:60],
line[60:67], line[67:])
…将获得列
因此,只需在行上循环,将每行拆分为列,然后找到正确的列:
def parse_log(log)
for line in log.splitlines():
if line[29:42].rstrip() == 'notconnect':
yield line[:10].rstrip()
notconnect_interfaces = list(parse_log(log))
如果您想要更一般的东西,只需编写一个列拆分函数,它接受一行和一系列列边界
def parse_line(line, columns):
for start, stop in zip(columns, columns[1:])
yield line[start, stop].rstrip()
def parse_log(log):
for line in log.splitlines():
yield list(parse_line(line, (0, 10, 29, 42, 53, 60, 67, 80)))
def find_notconnected(log):
for port, name, status, vlan, duplex, speed, type in parse_log(log):
if status == 'notconnect':
yield port
您还可以将其转换为一个GeneXPR序列,而不是一组函数。更简洁一点,但可能不那么可读:
bounds = (0, 10, 29, 42, 53, 60, 67, 80)
columns = ([line[start:stop].rstrip() for start, stop in zip(bounds, bounds[1:])]
for line in log.splitlines())
notconnected = (port for port, _, status, _, _, _, _ in columns
if status == 'notconnected')
看起来正则表达式应该是有序的,不是吗?我觉得我可以找到“notconnect”字符串,但是如何返回并获得它前面的Gi1/0/4呢?有时它可能是Gi1/4或Fa0/2或Gi1/1/24…一个regexp似乎不是解析固定列宽表的最佳方式…它似乎可以做我希望它做的事情,但它是在一条长线中输出整个内容,每个“线”之间有一整束\r\n。我如何将它们分割成单独的“行”?做一个log.encode('ascii')行吗?@Sumico:我没有写任何输出任何东西的代码,只是给你一个接口列表的代码。如果您想在每行打印一个,您可以在parse_log(log)中对接口执行
print('\n.join(notconnect_interfaces))
,或:print(interface)
或其他任何操作。@Sumico:或者,如果您问如何将输入拆分为行……这就是splitlines
函数的功能。我会试一试。我在问如何将输入分成几行。