Python - 阅读特定的文本行
Python - Read Specific Lines of Text
我正在尝试搜索文件中的特定文本。然后打印该行之前的行,以及所有以特定字符开头的后续行,尤其是 'space.'
这是我尝试读取的文件示例:
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 address'时,我想打印之前的行,然后打印该界面下的所有配置项。
目前,我正在从文件目录中读取并从文件中输出特定信息。这是代码:
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 行中声明 "interface",所以这就是我不想搜索该文本的原因,并且不能保证感叹号会是最后一项,尽管它是极有可能。这就是为什么我正在寻找一种方法来读取基于 'IP address' 和空格的行。
我对 Python 和一般编程还是个新手,但看起来 this 之类的东西可能会有帮助。我只是不完全理解它是如何工作的。
有什么想法可以实现吗?另外,我正在尝试使用 Python 3.x.
使用 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"
)
})
这是上面推荐的 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'],
可以使用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”的接口的结果无效
我正在尝试搜索文件中的特定文本。然后打印该行之前的行,以及所有以特定字符开头的后续行,尤其是 'space.'
这是我尝试读取的文件示例:
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 address'时,我想打印之前的行,然后打印该界面下的所有配置项。
目前,我正在从文件目录中读取并从文件中输出特定信息。这是代码:
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 行中声明 "interface",所以这就是我不想搜索该文本的原因,并且不能保证感叹号会是最后一项,尽管它是极有可能。这就是为什么我正在寻找一种方法来读取基于 'IP address' 和空格的行。
我对 Python 和一般编程还是个新手,但看起来 this 之类的东西可能会有帮助。我只是不完全理解它是如何工作的。
有什么想法可以实现吗?另外,我正在尝试使用 Python 3.x.
使用 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"
)
})
这是上面推荐的 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'],
可以使用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”的接口的结果无效