1

我正在尝试在文件中搜索特定文本。然后打印该行之前的行,以及以特定字符开头的所有后续行,特别是“空格”。

这是我正在尝试读取的文件示例:

interface vlan 22
 ip address 10.10.2.1 255.255.255.0
 ip helper-address 10.10.44.1
 ip helper-address 10.10.44.2
!
interface vlan 23
 ip address 10.10.23.1 255.255.255.0
 ip helper-address 10.10.44.1
 ip helper-address 10.10.44.2
!

当我看到“IP 地址”时,我想立即打印该行,然后打印该界面下的所有配置项。

目前,我正在读取文件目录并从文件中输出特定信息。这是代码:

for file in glob.glob('*.log'):
with open(file) as search:
    with open(queryoutput,"a") as foutput:
        for line in search:
            line = line.rstrip()
            if hostcheck in line:
                hostentry = line.split("hostname ")[1]
                foutput.write("Subnet information below is from " + hostentry + "\n")
            elif ipaddress in line:
                foutput.write("Local Device: " + hostentry + "\n")
                foutput.write("Remote " + line + "\n")

并非所有网络设备都会在 VLAN 行中声明“接口”,这就是为什么我不想搜索该文本的原因,并且不能保证感叹号会是最后一项,尽管很有可能。这就是为什么我正在寻找一种基于“IP 地址”和空格来读取行的方法。

我对 Python 和一般编程仍然很陌生,但看起来像这样的东西可能会有所帮助。我只是不完全理解它是如何工作的。

关于我如何做到这一点的任何想法?另外,我正在尝试使用 Python 3.x。

4

3 回答 3

2

It would probably be easier to utilize a Cisco config-parsing library rather than start from first principles.

For example, the ciscoconfparse module makes your problem as easy as the following, creating a dict with each interface mapped to a list of its configuration items. Searching for other object types would just be a matter of changing the argument to find_objects.

Assuming we're dealing with a file named test-config:

import pprint
from ciscoconfparse import CiscoConfParse

parse = CiscoConfParse("test-config", syntax="ios")

pprint.pprint({
    obj.text: [child.text.strip() for child in obj.children]
    for obj in parse.find_objects(r"interface")
})

Result:

{'interface vlan 22': ['ip address 10.10.2.1 255.255.255.0',
                       'ip helper-address 10.10.44.1',
                       'ip helper-address 10.10.44.2'],
 'interface vlan 23': ['ip address 10.10.23.1 255.255.255.0',
                       'ip helper-address 10.10.44.1',
                       'ip helper-address 10.10.44.2']}

Edit: Regarding your additional question, it would probably be wise to read the documentation and tutorial for the module which contains, among other things, examples of how to search for entries with specific children. To achieve what you're asking for, you could modify the above to use the find_objects_w_child() function:

pprint.pprint({
    obj.text: [child.text.strip() for child in obj.children]
    for obj in parse.find_objects_w_child(
        parentspec=r"^interf", childspec=r"ip .*address"
    )
})
于 2019-02-23T01:28:03.473 回答
0

这是上面推荐的 ciscoconfparse 的示例。这实际上非常有用。只是想知道我是否可以以某种方式排除设备的所有开关接口。

     'interface FastEthernet0/7': ['spanning-tree portfast'],
 'interface FastEthernet0/8': ['switchport access vlan 300',
                               'switchport mode access',
                               'authentication event fail action next-method',
                               'authentication event server dead action reinitialize vlan 999',
                               'authentication host-mode multi-auth',
                               'authentication order dot1x mab',
                               'authentication priority dot1x mab',
                               'authentication port-control auto',
                               'mab eap',
                               'dot1x pae authenticator',
                               'spanning-tree portfast'],
 'interface FastEthernet0/9': ['switchport access vlan 300',
                               'switchport mode access',
                               'authentication event fail action next-method',
                               'authentication event server dead action reinitialize vlan 999',
                               'authentication host-mode multi-auth',
                               'authentication order dot1x mab',
                               'authentication priority dot1x mab',
                               'authentication port-control auto',
                               'mab eap',
                               'dot1x pae authenticator',
                               'spanning-tree portfast'],
 'interface GigabitEthernet0/1': [],
 'interface GigabitEthernet0/2': [],
 'interface Vlan1': ['no ip address', 'shutdown'],
 'interface Vlan300': ['ip address 172.22.0.1 255.255.255.0',
                       'ip helper-address 10.208.111.196',
                       'ip helper-address 10.208.111.195'],
 'interface Vlan310': ['ip address 172.31.200.1 255.255.255.0',
                       'ip access-group guest-restrictions in',
                       'ip helper-address 10.208.111.195',
                       'ip helper-address 10.208.111.196'],
 'interface Vlan500': ['ip address 172.19.0.2 255.255.255.248'],
于 2019-02-23T19:12:56.630 回答
0

您可以使用TTP来解析上述文本,代码如下:

from ttp import ttp

data = """
interface vlan 22
 ip address 10.10.2.1 255.255.255.0
 ip helper-address 10.10.44.1
 ip helper-address 10.10.44.2
!
interface vlan 23
 ip address 10.10.23.1 255.255.255.0
 ip helper-address 10.10.44.1
 ip helper-address 10.10.44.2
!
interface Fast0/31
 switchport
!
interface vlan 77
 description Not In Use
!
"""

template = """
<group contains="ip">
interface {{ interface | ORPHRASE }}
 ip address {{ ip }} {{ mask }}
 ip helper-address {{ dhcp | to_list | joinmatches }}
</group>
"""

parser = ttp(data, template)
parser.parse()
print(parser.result(format="json")[0])

将打印:

[
    [
        {
            "dhcp": [
                "10.10.44.1",
                "10.10.44.2"
            ],
            "interface": "vlan 22",
            "ip": "10.10.2.1",
            "mask": "255.255.255.0"
        },
        {
            "dhcp": [
                "10.10.44.1",
                "10.10.44.2"
            ],
            "interface": "vlan 23",
            "ip": "10.10.23.1",
            "mask": "255.255.255.0"
        }
    ]
]

TTP 允许根据产生的匹配过滤结果,在这种特殊情况下,组“包含”功能使与“ip”不匹配的接口的结果无效

于 2020-07-27T10:26:26.013 回答