[英]How to parse Cisco IOS output into an object or JSON
现在,我可以通过如下所示的简单re.split("\\n([^\\s])", data)
获得几乎我想要的东西,但问题是结果列表包含单个非空白字符匹配,因为它是列表中的自己的项目。 脚本下方的示例输出。 注意“VLAN”中的“V”是如何作为它自己的项目被捕获的?
我还想知道是否有更好的方法来做到这一点,也许我可以包含一个库来处理将表格数据转换为字典或其他东西。
#!/usr/bin/python
import re
import sys
data = """
VLAN Name Status Ports
---- -------------------------------- --------- -------------------------------
1 default active Fa0/2, Fa0/3, Fa0/4, Fa0/5, Fa0/6, Fa0/7
Fa0/8, Fa0/9, Fa0/10, Fa0/11, Fa0/12
Fa0/13, Fa0/14, Fa0/15, Fa0/16, Fa0/17
Fa0/18, Fa0/19, Fa0/20, Fa0/21, Fa0/22
Fa0/23, Fa0/24, Gi0/2
1002 fddi-default act/unsup
1003 token-ring-default act/unsup
1004 fddinet-default act/unsup
1005 trnet-default act/unsup
"""
lines = re.split("\n([^\s])", data)
print lines
输出:
['', 'V', 'LAN 名称状态端口', '-', '--- --------------------------- ----- --------- -------------------------------', '1' , ' 默认激活 Fa0/2, Fa0/3, Fa0/4, Fa0/5, Fa0/6, Fa0/7\\n
Fa0/8、Fa0/9、Fa0/10、Fa0/11、Fa0/12\\n
Fa0/13、Fa0/14、Fa0/15、Fa0/16、Fa0/17\\n
Fa0/18、Fa0/19、Fa0/20、Fa0/21、Fa0/22\\n
Fa0/23, Fa0/24, Gi0/2', '1', '002 fddi-default
act/unsup', '1', '003 token-ring-default act/unsup', '1', '004 fddinet-default act/unsup', '1', '005 trnet-default act/unsup\\n' ]
谢谢!
编辑:
(nm 不起作用,抱歉)但是这整个事情仍然感觉很hacky 所以我很想听听任何其他建议。lines = re.findall(".*[^\\n\\W]*", data)
似乎它可能是一个更好的方法
NTC 模板提供了一组模板来解析各种 Cisco IOS 命令输出(和其他网络设备)。 模板与TextFSM一起进行实际解析。
例如:
>>> from ntc_templates.parse import parse_output
>>> vlan_output = (
"VLAN Name Status Ports\n"
"---- -------------------------------- --------- -------------------------------\n"
"1 default active Gi0/1\n"
"10 Management active \n"
"50 VLan50 active Fa0/1, Fa0/2, Fa0/3, Fa0/4, Fa0/5,\n"
" Fa0/6, Fa0/7, Fa0/8\n"
)
>>> vlan_parsed = parse_output(platform="cisco_ios", command="show vlan", data=vlan_output)
>>> vlan_parsed
[
{
'vlan_id': '1',
'name': 'default',
'status': 'active',
'interfaces': ['Gi0/1']
},
{
'vlan_id': '10',
'name': 'Management',
'status': 'active',
'interfaces': []
},
{
'vlan_id': '50',
'name': 'VLan50', 'status': 'active',
'interfaces': ['Fa0/1', 'Fa0/2', 'Fa0/3', 'Fa0/4', 'Fa0/5', 'Fa0/6', 'Fa0/7', 'Fa0/8']
}
]
>>>
这可能不是最好的方法,但至少是一个解决方案。 使用 regex 模块而不是 re 模块。
lines = regex.split("\n(?=[^\s])", data)
与内置 re 模块不同,regex 模块允许在零宽度匹配上进行拆分,因此您可以使用先行在下一个字符匹配的位置进行拆分。
参考:
这些天我建议查看一个专门的现有库来进行解析。 我发现的一个这样的示例库是ciscoconfparse ,它将把 IOS 配置(和其他一些配置)解析成行对象,这些对象维护对配置操作有用的子/父行关系。
我在 Mellanox 交换机(类似于 Cisco CLI)中的命令输出方面遇到了类似的问题。 但我使用以下方法解决了:
假设您的 CLI cmd 是
“显示接口 XXXXXXXXXXX”。
输出将是文本格式。 您可以直接以 json 格式获取输出,如下所示:
“显示接口 XXXXXXXXXXX | json-print”
一旦你在变量中得到命令输出,在你的 python 脚本中说“输出”。 您可以将其转换为 json 对象,如下所示:
输出 = json.loads(输出)
希望这可以帮助。
解析它并转换为结构化数据的另一种方法。
模板文本解析器可以帮助生成您需要的结果,示例代码:
from ttp import ttp
from pprint import pprint
template = """
<input load="text">
VLAN Name Status Ports
---- -------------------------------- --------- -------------------------------
1 default active Fa0/2, Fa0/3, Fa0/4, Fa0/5, Fa0/6, Fa0/7
Fa0/8, Fa0/9, Fa0/10, Fa0/11, Fa0/12
Fa0/13, Fa0/14, Fa0/15, Fa0/16, Fa0/17
Fa0/18, Fa0/19, Fa0/20, Fa0/21, Fa0/22
Fa0/23, Fa0/24, Gi0/2
1002 fddi-default act/unsup
1003 token-ring-default act/unsup
1004 fddinet-default act/unsup
1005 trnet-default act/unsup
</input>
<group>
{{ vid | DIGIT | _start_ }} {{ name }} {{ status }}
{{ vid | DIGIT | _start_ }} {{ name }} {{ status }} {{ ports | ORPHRASE | replace(" ", "") | split(",") | joinmatches() }}
{{ ports | ORPHRASE | replace(" ", "") | split(",") | joinmatches() }}
</group>
"""
parser = ttp(template=template)
parser.parse()
pprint(parser.result())
# Prints:
# [[[{'name': 'default',
# 'ports': ['Fa0/2',
# 'Fa0/3',
# 'Fa0/4',
# 'Fa0/5',
# 'Fa0/6',
# 'Fa0/7',
# 'Fa0/8',
# 'Fa0/9',
# 'Fa0/10',
# 'Fa0/11',
# 'Fa0/12',
# 'Fa0/13',
# 'Fa0/14',
# 'Fa0/15',
# 'Fa0/16',
# 'Fa0/17',
# 'Fa0/18',
# 'Fa0/19',
# 'Fa0/20',
# 'Fa0/21',
# 'Fa0/22',
# 'Fa0/23',
# 'Fa0/24',
# 'Gi0/2'],
# 'status': 'active',
# 'vid': '1'},
# {'name': 'fddi-default', 'status': 'act/unsup', 'vid': '1002'},
# {'name': 'token-ring-default', 'status': 'act/unsup', 'vid': '1003'},
# {'name': 'fddinet-default', 'status': 'act/unsup', 'vid': '1004'},
# {'name': 'trnet-default', 'status': 'act/unsup', 'vid': '1005'}]]]
注意 group 中的最后一行,它应该有准确数量的前导空格作为要解析的实际文本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.