我有一个路由器配置文件。路由器有数千个"接口",我试图确保它在EACH接口配置部分中有两个某些线路。典型的路由器配置文件如下所示:
<whitespaces> Interface_1
<whitespaces> description Interface_1
<whitespaces> etc etc'
<whitespaces> etc etc etc
<whitespaces> <config line that i am searching to confirm is present>
<whitespaces> etc etc etc etc
!
!
! random number of router lines
<whitespaces> <second config line that i am searching to confirm is
present>
!
<whitespaces> Interface_2
<whitespaces> description Interface_2
<whitespaces> etc etc
<whitespaces> etc etc etc
<whitespaces> <config line that I am searching to confirm is present>
<whitespaces> etc etc etc etc
! random number of router lines
<whitespaces> <second config line that i am searching to confirm is
present>
etc
所以我有效地想要这个逻辑: - 通过路由器配置。当你看到Interface_X时,请在此之后留意两行,并确保它们出现在配置中。然后转到下一个界面,并一遍又一遍地做同样的事情。
这是棘手的部分: - 我希望这两行都在Interface配置中,而python需要知道搜索区域&#39;在下一个Interface_Y配置之后是接口_X和BEFORE之前的任何一行。 - 我搜索的两条线在配置中是随机间隔的,它们不像Interface_X之后的第10行和第12行。它们可以出现在Interface_X和Interface_Y之间的任何位置(下一个接口定义)。
死亡。已经四天了,似乎无法正确匹配 实际上,我只是希望python脚本吐出输出,说明示例: &#34; Interface_22和Interface_89缺少你正在寻找Tom&#34;的两行。我不在乎接口是否正确,我真的只关心接口配置何时错误。
file_name = 'C:\\PYTHON\\router.txt'
f = open(file_name, 'r')
output_string_obj = f.read()
a = output_string_obj.splitlines()
for line in a:
if re.match("(.*)(Interface)(.*)", line):
# logic to search for the presence of two lines after matching
# Interface, but prior to next instance of a Interface
# definition
if re.match("(.*)(check-1-line-present)(.*)", line + ???):
if re.match("(.*)(check-2-line-present)(.*)", line ?):
print ("This Interface has the appropriate config")
else:
print ("This Interface is missing the key two lines")
垂死的家伙。这是我在本次发布会上发布的第一个问题。我会采取任何人的想法/逻辑流程/陈述/想法。我进入这种类型的搜索情况很多,我不知道在路由器配置中哪些东西丢失了,但我知道它必须介于A点和B点之间,但没有其他任何内容#39抓握&#39;到.... &#39;&#39;&#39; &#39;
答案 0 :(得分:0)
配置文件不会太大。概念将通过配置文件循环搜索,搜索逻辑,但每个单独的文件都不是太大。假设这个问题小配置文件,但我明白你的观点。
示例配置与此类似:(今晚病例)
Interface_1 线 线 线 ip-address x.x.x.x. 线 线 Dhcp y.y.y.y 线 ! ! Interface_2 线 线 线 ip-address z.z.z.z 线 线 Dhcp y.y.y.y 线 ! ! 但它的静态配置,我有&#34; Line&#34;可能是30行或10行,或者其他什么。但是我正在寻找的两个词:&#34; ip-address&#34;和&#34; dhcp&#34;之后的东西,是独一无二的。
基本上我正在检查以确保配置同时配置了ip地址和dhcp!
答案 1 :(得分:0)
我根据你的信息给它一个镜头。概括地说,这个想法如下。
定义与^[\s]*(Interface_\d)
使用该字符串拆分配置 - 结果是以下格式的字符串数组 a)空字符串 b)接口名称 c)接口配置
检查以下模式是否匹配<config line
<second config line
。如果两者匹配打印Previous接口。以下是完整的代码,您可以根据自己的需要进行解决。
- 代码
config = """
Interface_1
description Interface_1
etc etc'
etc etc etc
ip-address 10.0.0.2
etc etc etc etc
!
!
! random number of router lines
dhcp 10.0.0.1
!
Interface_2
description Interface_2
etc etc
etc etc etc
ip-address 10.0.0.5
etc etc etc etc
! random number of router lines
note: no d-hcp
"""
import re
r = re.compile(r'^[\s]*(Interface_\d+)', re.MULTILINE)
r1 = re.compile(r'ip-address')
r2 = re.compile(r'dhcp')
configs = re.split(r, config)
for i, c in enumerate(configs):
if r.match(c):
continue
if r1.search(c) and r2.search(c):
print configs[i-1]
这可能不完美,但应该让你知道如何去做。同意这可能不是最易于编写的方式 - 但除非你能发布'真正的文件摘录',否则这是不可能的 - 这可能是不可能的?
答案 2 :(得分:0)
不确定您的文件实际上是什么样子但是如果实际上是空格,您可以使用Interface_
itertools.groupby
对行进行剥离和分组:
lines = ["<second config line that i am searching to confirm is present>"
,"<config line that i am searching to confirm is present>"]
from itertools import groupby
with open("out.txt") as f:
d = {}
groups = groupby(f, lambda x: x.strip().startswith("Interface_"))
for k, v in groups:
if k:
key = list(v)[0].strip()
data = " ".join(next(groups, " ")[1])
d[key] = all(l in data for l in lines)
print(d)
输入:
Interface_1
description Interface_1
etc etc'
etc etc etc
<config line that i am searching to confirm is present>
etc etc etc etc
!
!
! random number of router lines
<second config line that i am searching to confirm is present>
!
Interface_2
description Interface_2
etc etc
etc etc etc
<config line that i am searching to confirm is present>
etc etc etc etc
! random number of router lines
<second config line that i am searching to confirm is present>
输出:
{'Interface_2': True, 'Interface_1': True}
或者将正则表达式传递给groupby:
lines = ["<second config line that i am searching to confirm is present>"
,"<config line that i am searching to confirm is present>"]
from itertools import groupby
import re
with open("out.txt") as f:
d = {}
groups = groupby(f, lambda x: re.search("<whitespaces>\s+Interface_\d+",x))
for k, v in groups:
if k:
key = list(v)[0].strip().split()[1]
data = " ".join(next(groups, " ")[1])
d[key] = all(l in data for l in lines)
print(d)
输入:
<whitespaces> Interface_1
<whitespaces> description Interface_1
<whitespaces> etc etc'
<whitespaces> etc etc etc
<whitespaces> <config line that i am searching to confirm is present>
<whitespaces> etc etc etc etc
!
!
! random number of router lines
<whitespaces> <second config line that i am searching to confirm is present>
!
<whitespaces> Interface_2
<whitespaces> description Interface_2
<whitespaces> etc etc
<whitespaces> etc etc etc
<whitespaces> <config line that i am searching to confirm is present>
<whitespaces> etc etc etc etc
! random number of router lines
<whitespaces> <second config line that i am searching to confirm is present>
输出:
{'Interface_2': True, 'Interface_1': True}
一旦你有东西传递给groupby,它会将文件分成几个部分,你也可以用编译的正则表达式搜索替换in
搜索。
import re
regs = [re.compile("<second config line that i am searching to confirm is present>")
,re.compile("<config line that i am searching to confirm is present>")]
from itertools import groupby
with open("out.txt") as f:
d = {}
groups = groupby(f, lambda x: x.startswith("<whitespaces> Interface_"))
for k, v in groups:
if k:
key = list(v)[0].strip().split()[1]
data = " ".join(next(groups, " ")[1])
d[key] = all(reg.search(data) for reg in regs)
如果你确定这些行总是<whitespaces>
一个空格后跟Interface_
,你可以使用它作为分隔符:
groups = groupby(f, lambda x: x.startswith("<whitespaces> Interface_"))
这不会立即将所有数据读入内存,所以如果你有数百万行,它将会很有效。
答案 3 :(得分:0)
将您的文件读入行列表。
with open('C:\\PYTHON\\router.txt') as config:
lines = config.readlines()
剥去空白。
lines = [ln.strip() for ln in lines]
按接口名称获取字典中接口行的索引。
interfaces = {name: num for num, name in enumerate(lines)
if name.startswith('Interface_')}
检查您想要的行是否存在。
for name in interfaces.keys():
idx = interfaces[name]+2 # Shouldn't this be 3 to skip the description?
if not 'config item string' in lines[idx]:
print name, 'does not have the right config!'