2

我有数百个 cisco 配置文件,我需要(通过 python)找到在这种情况下 WIRELESS-IN 应用的具有特定服务策略的接口。我用来捕获接口的正则表达式是: pat=re.compile('(interface.*?)!$',re.DOTALL|re.M)

FastEthernet1/0/2在这种情况下,我需要返回。

样本数据可能是这样的:

我有一个正则表达式来将界面元素匹配到一个组中,但不是如何在该组中查找。任何人都可以帮忙吗?

interface FastEthernet1/0/1
 description Foo
 switchport access vlan 300
 switchport mode access
 switchport port-security aging time 2
 no logging event link-status
 speed 100
 duplex full
 priority-queue out
 mls qos trust dscp
 no snmp trap link-status
 no cdp enable
 spanning-tree portfast
 hold-queue 120 in
 hold-queue 200 out
 ip dhcp snooping trust
!
interface FastEthernet1/0/2
 description wlap2
 switchport access vlan 100
 switchport mode access
 switchport port-security maximum 15
 switchport port-security
 switchport port-security aging time 2
 switchport port-security aging type inactivity
 ip access-group 100 in
 no logging event link-status
 srr-queue bandwidth shape 0 0 0 10
 queue-set 2
 priority-queue out
 no snmp trap link-status
 storm-control broadcast level pps 100 50
 storm-control multicast level pps 100 50
 storm-control action trap
 spanning-tree portfast
 spanning-tree bpduguard enable
 service-policy input WIRELESS_IN
 ip dhcp snooping limit rate 15
!
interface FastEthernet1/0/3
 description Test3
 switchport access vlan 199
 switchport mode access
 switchport port-security aging time 2
 no logging event link-status
 queue-set 2
 priority-queue out
 mls qos trust dscp
 no snmp trap link-status
 no cdp enable
 spanning-tree portfast
 service-policy input VOICE-LAN

我拼凑了这段代码:

import re,string
f = open("sampleconfig.cfg")
cfgdata = f.read()
pat=re.compile('(interface.*?)!$',re.DOTALL|re.M)
pat2 = re.compile("service-policy.input.WIRELESS-IN")

data = pat.findall(cfgdata)
i=0
while i < len(data):
    if  pat2.findall(data[i]):
        print (data[i].split("\n")[0])
        i = i+1

    else:
        i = i+1
        pass
4

4 回答 4

8

我有数百个 cisco 配置文件,我需要(通过 python)找到在这种情况下 WIRELESS-IN 应用的具有特定服务策略的接口。我用来捕获接口的正则表达式是: pat=re.compile('(interface.*?)!$',re.DOTALL|re.M) ...

FastEthernet1/0/2在这种情况下,我需要返回。

回答:

您应该使用ciscoconfparse 1 ...假设我将您的配置存储在一个名为stackoverflow_question.conf...

>>> from ciscoconfparse import CiscoConfParse
>>> parse = CiscoConfParse('stackoverflow_question.conf')
>>> # .find_parents_w_child() returns a list of matching parent conf lines
>>> wifi_qos_intfs = parse.find_parents_w_child('^interface', 'WIRELESS_IN')
>>> print(wifi_qos_intfs)
['interface FastEthernet1/0/2']
>>>

这个怎么运作

ciscoconfparse的 API 相当简单;它将思科配置分解为父/子。 service-policy input WIRELESS_IN被认为是 的孩子interface FastEthernet1/0/2

当您调用 时CiscoConfParse(configuration_file)ciscoconfparse建立与 Cisco IOS 配置行的关系,作为父子语句;返回具有所有这些关系的对象。然后parse.find_parents_w_child(parentstr, childstr),是上述对象上的一个方法,它遍历配置并返回匹配的文本行列表parentstr,并且有一个或多个匹配的子级childstr

我使用了一个正则表达式^interface来保证parentstr只匹配 Cisco IOS 接口行。而不是其他可能interface在其中使用该词的语句。


1全面披露:我是ciscoconfparse的作者。

于 2014-02-08T19:18:42.040 回答
1

这是否是一种更好的方法是有争议的,但至少有些不同:

import re,string
f = open("sampleconfig.cfg")
cfgdata = f.read()
pat = '(?sm)interface (\S*)(?:(?!^!$).)*service-policy.input.WIRELESS_IN.*?!$'
data = re.findall(pat, cfgdata)
于 2014-09-16T12:42:39.883 回答
1

解决此任务的另一种方法是使用带有匹配结果过滤的TTP模块(我是该模块的作者),例如以下代码:

my_template="""
<group 
name="interfaces_with_WIRELESS-IN_policy.{{ interface }}" functions="contains(policy)">
interface {{ interface }}
 service-policy input {{ policy | equal(WIRELESS_IN) }}
</group>
"""

from ttp import ttp
parser = ttp(template=my_template)
parser.parse()
print(parser.result(format="json")[0])

会产生这样的结果:

[
    {
        "interfaces_with_WIRELESS-IN_policy": {
            "FastEthernet1/0/2": {
                "policy": "WIRELESS_IN"
            }
        }
    }
]

这个怎么运作

TTP 解析 OP 提供的文本数据以提取附加到它们的接口和策略,而无需任何过滤将产生这些结果:

[
    {
        "interfaces_with_WIRELESS-IN_policy": {
            "FastEthernet1/0/1": {},
            "FastEthernet1/0/2": {
                "policy": "WIRELESS_IN"
            },
            "FastEthernet1/0/3": {
                "policy": "VOICE-LAN"
            }
        }
    }
]

但是通过使用匹配变量函数“equal”,我们可以指示 TTP 使不等于“WIRELESS_IN”的匹配结果无效,此外,在为 group 定义 functions="contains(policy)" 后,TTP 将检查 group 结果(其中是python字典)具有名为“policy”的键,没有这样的键会使组匹配结果无效。

但是,在您应用另一个 TTP 组函数“itemize”之前,上面的代码不会生成接口列表(根据 OP 的要求),这将创建组结果中的项目列表,例如模板:

my_template="""
<group 
name="interfaces_with_WIRELESS-IN_policy" functions="contains(policy) | itemize(interface)">
interface {{ interface }}
 service-policy input {{ policy | equal(WIRELESS_IN) }}
</group>
"""

将发出这些结果:

[
    {
        "interfaces_with_WIRELESS-IN_policy": [
            "FastEthernet1/0/2"
        ]
    }
]
于 2019-11-23T10:40:19.533 回答
0
    import re,string
f = open("sampleconfig.cfg")
cfgdata = f.read()
pat=re.compile('(interface.*?)!$',re.DOTALL|re.M)
pat2 = re.compile("service-policy.input.WIRELESS-IN")

data = pat.findall(cfgdata)
i=0
while i < len(data):
    if  pat2.findall(data[i]):
        print (data[i].split("\n")[0])
        i = i+1

    else:
        i = i+1
        pass
于 2013-10-01T16:56:37.980 回答