繁体   English   中英

如何将 Cisco IOS 输出解析为对象或 JSON

[英]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' ]

谢谢!

编辑 lines = re.findall(".*[^\\n\\W]*", data)似乎它可能是一个更好的方法 (nm 不起作用,抱歉)但是这整个事情仍然感觉很hacky 所以我很想听听任何其他建议。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM