0

第一次发布关于 Python 的持续学习。

目前,我遇到了一件非常简单的事情:我有一个路由器的输出 - 一个名为“接口”的列表 - 打印时看起来像这样:

set interfaces ge-0/0/0 unit 0 family inet address 192.168.15.66/24
set interfaces ge-0/0/1 unit 0 family inet dhcp
set interfaces ge-0/0/2 unit 0 family inet address 1.1.1.1/30
set interfaces ge-0/0/2 unit 0 family inet address 192.168.99.1/30

使用 re 模块(findall),我正在查找并匹配一些我需要的关键字,如下所示:

pattern1 = re.compile(r'ge.{1,7}')
pattern2 = re.compile(r'dhcp')
matched1 = pattern1.findall(interfaces)
matched2 = pattern2.findall(interfaces)

此时,问题是:如果此路由器输出的行(?)包含单词“dhcp”,我想保存/存储该值并获取接口名称/编号。在上面的示例中,包含“dhcp”的接口是“ge-0/0/1”。如果我走在正确的道路上,你们知道吗?

  • 模型(获取两个正则表达式)是否有用,然后将两个值合并到字典中,然后使用 return 打印?
  • 如何解析其余的路由器代码行,以查找此“dhcp”值,然后如果没有匹配可以返回“无”或“不存在”输出?

预期的输出将如下所示(我使用“返回表格”来打印输出):

| interface   | service    |
|-------------+------------|
| ge-0/0/0    |  none      | 
| ge-0/0/1    |  dhcp      | 
| ge-0/0/2    |  none      |

任何指导,将受到欢迎。谢谢。


编辑:到目前为止,感谢您的回答。我正在添加更多信息,因为可能是关键。我获得路由器输出的方式是使用 SaltStack 集成模块。我正在使用以下语法从 Salt Master 运行该 python 文件:

interfaces = __salt__['net.cli']('show configuration interfaces | display set', format='xml')['out']['show configuration interfaces | display set']

我真诚地希望输出实际上是一个列表。

与此同时,我使用以下内容进行了另一次尝试:

def dhcp():

interfaces = __salt__['net.cli']('show configuration interfaces | display set', format='xml')['out']['show configuration interfaces | display set']

pattern = re.findall(r'ge.{1,7}', interfaces)
pattern1 = re.findall(r'dhcp', interfaces)

return pattern, pattern1 

输出是这样的:

outright ~  sudo salt 'vsrx1' red.dhcp
vsrx1:
 |_
   - ge-0/0/0 
   - ge-0/0/0 
   - ge-0/0/0 
   - ge-0/0/0 
   - ge-0/0/1 
   - ge-0/0/2 
   - ge-0/0/2 
 |_
   - dhcp

单独打印列表(使用 --> return("List is: " + str(pattern)) )

 outright ~  sudo salt 'vsrx1' red.dhcp
 vsrx1:
 List is: ['ge-0/0/0 ', 'ge-0/0/0 ', 'ge-0/0/0 ', 'ge-0/0/0 ', 'ge-0/0/1 ', 'ge-0/0/2 ', 'ge-0/0/2 ']

如果表达问题的方式在技术上很差,我深表歉意。我仍在学习一般术语。

4

3 回答 3

1

在我看来,您似乎走在正确的轨道上。这是我对您所要求的内容的解释。希望这可以帮助。注意:我是通过手机完成的,所以请原谅不正确的缩进

import re

s = ["set interfaces ge-0/0/0 unit 0 family inet address 192.168.15.66/24",
"set interfaces ge-0/0/1 unit 0 family inet dhcp", "set interfaces ge-0/0/2 unit 0 family inet address 1.1.1.1/30", 
"set interfaces ge-0/0/2 unit 0 family inet address 192.168.99.1/30"]

print("interfaces | services")
mydict ={}
def parse_addresses():
    for i in s:
            interface = re.search(r"ge.{1,7}", i)
            if "dhcp" in i:
                service = "dhcp"
                mydict.setdefault("router",{interface.group(): service})
            else:
                service = "None"
            print(f"{interface.group()} | {service}")
    if bool(mydict):
        return mydict
    return "None"

print(parse_addresses())
于 2020-04-16T16:15:18.433 回答
0

感谢所有在几个可能的方向上查看和指导我的人。我正在回答我自己的问题(至少 90%)。我的最终脚本如下(是的,我知道我的代码可以 100% 改进,但这是我为实现目标所做的):

定义最终():

interfaces = []
output_table1 = []
output_table2 = []

interfaces = __salt__['net.cli']('show configuration interfaces | display set', format='xml')['out']['show configuration interfaces | display set']

# Saving output into a file for further use
with open("/srv/salt/_modules/aaa.txt", "w") as file:
    file.write(interfaces)

# Regex patterns to match things
regex1 = re.compile(r'(ge.{1,7}.{7}).*?(?=sampling)')
match_reg1 = regex1.finditer(interfaces)

regex2 = re.compile(r'ge.{1,7}.{7}')
match_reg2 = regex2.finditer(interfaces)


# IF stataments and FOR, to match and append items
if match_reg1:
    output_table1.insert(0, "Sampled interfaces")
    for match1 in match_reg1:
        output_table1.append(match1.group(1))

if match_reg2:
    output_table2.insert(0, "Not sampled interfaces")
    for match2 in match_reg2:
        output_table2.append(match2.group())

# Differences between two tables: 
difference_list = []
for item in output_table2:
    if item not in output_table1:
        difference_list.append(item)

final = []
final.insert(0, "To enable sampling, insert the following on target device")
for line in difference_list:
    final.append("set interfaces " + line + "family inet sampling [input/output]")

return output_table1, difference_list, final

在上面之后,我的输出是:

terminal# sudo salt 'vsrx1' red.final
vsrx1:
|_
  - Sampled interfaces
  - ge-0/0/1 unit 0 
  - ge-0/0/1 unit 0 
|_
  - Not sampled interfaces
  - ge-0/0/0 descrip
  - ge-0/0/0 unit 0 
  - ge-0/0/2 unit 0 
  - ge-0/0/2 unit 0 
|_
  - To enable sampling, insert the following on target device
  - set interfaces Not sampled interfacesfamily inet sampling [input/output]
  - set interfaces ge-0/0/0 descripfamily inet sampling [input/output]
  - set interfaces ge-0/0/0 unit 0 family inet sampling [input/output]
  - set interfaces ge-0/0/2 unit 0 family inet sampling [input/output]
  - set interfaces ge-0/0/2 unit 0 family inet sampling [input/output]

请记住,我正在使用 Saltstack 代理 minions 从 Juniper vSRX 设备中提取信息。我现在需要练习更多的 REGEX 来删除所有不必要的输出数据,并且更准确地了解我想要看到的内容,就像上面的示例(仍然很脏),但基本目标已经实现。

我一开始遇到的另一个挑战是理解“interfaces = salt ['net.cli']('show configuration interfaces...”的输出是因为我认为每个路由器命令行都是我内部的一个项目/行。列表。将其保存在“aaa.txt”文件中然后打印时,它的打印与我的想法不同:

这是 VisualCode 打开的文件(名为 aaa.txt 的文件):

set interfaces ge-0/0/0 description vsrx1_descr_test
set interfaces ge-0/0/0 unit 0 family inet address 192.168.15.66/24
set interfaces ge-0/0/1 unit 0 family inet sampling input
set interfaces ge-0/0/1 unit 0 family inet sampling output
set interfaces ge-0/0/1 unit 0 family inet dhcp
set interfaces ge-0/0/2 unit 0 family inet address 1.1.1.1/30
set interfaces ge-0/0/2 unit 0 family inet address 192.168.99.1/30

这是函数打印的文件:

terminal# sudo salt 'vsrx1' red.final
vsrx1:

set interfaces ge-0/0/0 description vsrx1_descr_test
set interfaces ge-0/0/0 unit 0 family inet address 192.168.15.66/24
set interfaces ge-0/0/1 unit 0 family inet sampling input
set interfaces ge-0/0/1 unit 0 family inet sampling output
set interfaces ge-0/0/1 unit 0 family inet dhcp
set interfaces ge-0/0/2 unit 0 family inet address 1.1.1.1/30
set interfaces ge-0/0/2 unit 0 family inet address 192.168.99.1/30

当更改 SALT 功能时:

interfaces = __salt__['net.cli']('show configuration interfaces | display set', format='xml')['out']['show configuration interfaces | display set']"
to this:
interfaces = __salt__['net.cli']('show configuration interfaces | display set', format='xml')['out']

输出是垂直打印的,如下所示:

s
e
t

i
n
t
e
r

等等。我被那个弄坏了。

希望这可以帮助。与往常一样,欢迎任何更正。

克里斯蒂安。

于 2020-05-15T20:28:55.867 回答
0

我不确定您如何获得路由器的输出。但这应该有效如果您的数据采用这种形式

interface_list = ['set interfaces ge-0/0/0 unit 0 family inet address 192.168.15.66/24',
'set interfaces ge-0/0/1 unit 0 family inet dhcp',
'set interfaces ge-0/0/2 unit 0 family inet address 1.1.1.1/30',
'set interfaces ge-0/0/2 unit 0 family inet address 192.168.99.1/30']

然后

interface_dict = {}
for element in interface_list:
    element_list = element.split(" ")
    if element_list[7] =='dhcp':
        interface_dict[element_list[2]] = 'dhcp'
    else:
        interface_dict[element_list[2]] = 'none'
print(interface_dict)

会给你

{'ge-0/0/0': 'none', 'ge-0/0/1': 'dhcp', 'ge-0/0/2': 'none'}

然后,您可以将字典更改为数据框

import pandas as pd

df = pd.Series(interface_dict).to_frame().reset_index().rename(columns={'index':'interface', 0:'service'})
df 
    interface   service
0   ge-0/0/0    none
1   ge-0/0/1    dhcp
2   ge-0/0/2    none

于 2020-04-16T02:17:15.763 回答