Python-阅读特定行的文本

时间:2019-02-23 00:05:27

标签: python networking cisco-ios ciscoconfparse

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

这是我要读取的文件示例:

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的新手,并且还是一般的编程人员,但是看起来像this可能会有所帮助。我只是不完全了解这将如何工作。

关于如何实现此目标的任何想法?另外,我正在尝试使用Python 3.x。

3 个答案:

答案 0 :(得分:2)

使用Cisco配置解析库可能比起初的原则更容易。

例如,ciscoconfparse模块使您的问题变得如下所示,创建一个字典,将每个interface映射到其配置项列表。搜索其他对象类型只需将参数更改为find_objects

假设我们正在处理一个名为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")
})

结果:

{'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']}

编辑:关于您的其他问题,最好阅读该模块的文档和教程,其中包括how to search for entries with specific children的示例。为了实现您的要求,您可以修改以上内容以使用find_objects_w_child()函数:

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"
    )
})

答案 1 :(得分:0)

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

b

答案 2 :(得分: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”不匹配的接口的结果无效