现在,我可以使用简单的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 Name Status Ports',' - ', '--- -------------------------------- --------- -------------------------------','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)
似乎可能是一种更好的方法
答案 0 :(得分:1)
NTC Templates提供了一组模板来解析各种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']
}
]
>>>
答案 1 :(得分:0)
这可能不是最好的方法,但它至少是一种解决方案。使用正则表达式模块而不是re模块。
drawLine()
与内置模块不同,正则表达式模块允许在零宽度匹配上进行拆分,因此您可以使用前瞻分割在下一个字符匹配的位置。
参考文献:
答案 2 :(得分:0)
这些天,我建议您看一下现有的专用库进行解析。我发现的一个这样的示例库是ciscoconfparse,它将把IOS配置(和其他一些配置)解析为行对象,这些对象保持子/父行关系对配置操作很有用。
答案 3 :(得分:0)
我在Mellanox交换机中有类似的命令输出问题(与Cisco CLI相似)。但是我使用以下方法解决了:
假设您的CLI cmd为
“显示界面XXXXXXXXXXX”。
输出将为文本格式。您可以直接以json格式获取输出,如下所示:
“显示界面XXXXXXXXXXX | json-print”
在python脚本中,一旦在变量中得到命令输出,即说“输出”。 您可以将其转换为json对象,如下所示:
output = json.loads(输出)
希望这会有所帮助。
答案 4 :(得分:0)
另一种解析它并将其转换为结构化数据的方法。
Template Text Parser可以帮助您产生所需的结果,示例代码:
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'}]]]
请注意组中的最后一行,它的前导空格应与要解析的实际文本的数量完全相同。