无法在第一个PAR之后检查列表中的空行

2024-10-01 09:31:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在分析来自Cisco的路由表。我只需要BGP条目。有一些奇怪的OSPF路由使线路与众不同。我不在乎那些。但因为行分割[8:10]是不同的,我最后写的是一个空行。我写的是network,netmask为0.0.0.0),但我想跳过最后写的空行。这是一个文件示例,以及解析它的代码。由于实际的文件是巨大的,我试图避免重复循环。你知道吗

编辑:目标是编写一个包含两列的csv文件,其中包含IP地址和网络掩码。你知道吗

B        10.34.86.0/24 [20/0] via 10.15.33.73, 2w3d
B        10.34.93.0/24 [20/0] via 10.15.33.73, 2w3d
O E1     10.34.95.0/24  <- DON'T CARE ABOUT HIM  
B        10.34.97.0/24 [20/0] via 10.15.33.73, 2w0d
B        10.34.98.0/24 [20/0] via 10.15.33.73, 2w3d

所需输出(注意O线不在那里)

10.34.86.0,24
10.34.93.0,24
10.34.97.0,24
10.34.98.0,24

还有我的Python3

import csv
import re
import time
timestr = time.strftime("%m%d%y")
with open('RemediationStatus' + timestr + '.csv', 'a', newline='') as csvfile:
    with open('routes-3-28.txt','r')as msroutes:
        headwrite = csv.writer(csvfile)
        headwrite.writerow(["Network", "Netmask"])
        for line in msroutes:
            firstpass = re.split(r'[\s,/]', line)
            finalpass = (firstpass[8:10])
            if not finalpass[0]:
                finalpass = (["0.0.0.0", "0.0.0.0"])
        print(finalpass)
        writer = csv.writer(csvfile)
        writer.writerow(finalpass)

Tags: 文件csvcsvfileimportretimeaswith
2条回答

您应该利用python中的re模块,如果我发现了您的逻辑,您会想要这样的东西:

import re

text = ''''B        10.34.86.0/24 [20/0] via 10.15.33.73, 2w3d
B        10.34.93.0/24 [20/0] via 10.15.33.73, 2w3d
O E1     10.34.95.0/24  <- DON'T CARE ABOUT HIM  
B        10.34.97.0/24 [20/0] via 10.15.33.73, 2w0d
B        10.34.98.0/24 [20/0] via 10.15.33.73, 2w3d'''

result = re.findall('B\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/(\d+)', text)
result
#[('10.34.86.0', '24'),
# ('10.34.93.0', '24'),
# ('10.34.97.0', '24'),
# ('10.34.98.0', '24')]

IIUC这里有一种使用regex的方法:

full_pattern = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,3} \[\d+/\d+]"
small_pattern = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,3}"

msroutes = [
    "B        10.34.86.0/24 [20/0] via 10.15.33.73, 2w3d",
    "B        10.34.93.0/24 [20/0] via 10.15.33.73, 2w3d",
    "O E1     10.34.95.0/24",
    "B        10.34.97.0/24 [20/0] via 10.15.33.73, 2w0d",
    "B        10.34.98.0/24 [20/0] via 10.15.33.73, 2w3d"
]

for line in msroutes:
    finalpass = re.findall(full_pattern, line)
    if finalpass:
        finalpass = re.findall(small_pattern, finalpass[0])
        finalpass = finalpass[0].split('/')
        print(finalpass)

#['10.34.86.0', '24']
#['10.34.93.0', '24']
#['10.34.97.0', '24']
#['10.34.98.0', '24']

因为我不确定是否有更简单的方法来忽略您要求忽略的行(可能是检查它是否以'B'开头还是以'O'开头?),我做了两次正则表达式搜索。第一种方法寻找与模式类似的东西:

##.##.##.##/## [##/#]

其中#表示一个数字。模式\d{1,3}表示1到3位数之间的匹配。这将消除其中没有[20/0]的行。你知道吗

接下来,对于匹配的行,我执行较小的regex搜索,只得到IP和Mask值。我们不必对这个进行错误检查,因为我们知道它已经匹配了更大的模式。你知道吗


如果您知道只想处理以'B'开头的行:

for line in msroutes:
    if line.startswith('B'):
        finalpass = re.findall(small_pattern, line)[0].split('/')
        print(finalpass)
#['10.34.86.0', '24']
#['10.34.93.0', '24']
#['10.34.97.0', '24']
#['10.34.98.0', '24']

也可以不使用长regex模式,只使用现有代码,将连续的空格视为一个空格,从而简化逻辑。你知道吗

for line in msroutes:
    firstpass = re.split(r'\s+', line)
    if len(firstpass) > 1 and "/" in firstpass[1]:
        finalpass = firstpass[1].split("/")
    else:
        finalpass = ["0.0.0.0", "0.0.0.0"]
    print(finalpass)
#['10.34.86.0', '24']
#['10.34.93.0', '24']
#['0.0.0.0', '0.0.0.0']
#['10.34.97.0', '24']
#['10.34.98.0', '24']

\s+表示匹配一个或多个空格。你知道吗

相关问题 更多 >