python:通过路由器配置搜索存在的某些行

时间:2015-05-31 17:18:12

标签: python regex search

我有一个路由器配置文件。路由器有数千个"接口",我试图确保它在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;

4 个答案:

答案 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)

我根据你的信息给它一个镜头。概括地说,这个想法如下。

  1. 定义与^[\s]*(Interface_\d)

  2. 匹配的正则表达式模式
  3. 使用该字符串拆分配置 - 结果是以下格式的字符串数组 a)空字符串 b)接口名称 c)接口配置

  4. 检查以下模式是否匹配<config line <second config line。如果两者匹配打印Previous接口。以下是完整的代码,您可以根据自己的需要进行解决。

  5. - 代码

    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!'