首页 > 解决方案 > 将输出 txt "show ip route" 解析为 csv

问题描述

我需要使用 python 代码来解析一个文本文件,其中包含来自多个路由器的路由表的输出(我将提供一个文本文件的示例)。我想得到一个结构,其中标题或第一列带有路由器的名称,然后是参数(路由协议、网络、掩码、AD、下一跳、时间)。但是用路由器的名字我不能。

这是一个要解析的文本文件:

..................THIS IS THE HOST IP ADDRESS...................
192.168.100.1

R1>show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       + - replicated route, % - next hop override

Gateway of last resort is not set

      90.0.0.0/24 is subnetted, 11 subnets
B        90.1.0.0 [20/0] via 192.168.100.2, 15:02:50
B        90.2.0.0 [20/0] via 192.168.100.2, 15:02:50
B        90.3.0.0 [20/0] via 192.168.100.2, 15:02:50
B        90.4.0.0 [20/0] via 192.168.100.2, 15:02:50
B        90.5.0.0 [20/0] via 192.168.100.2, 15:02:50
B        90.6.0.0 [20/0] via 192.168.100.2, 15:02:50
B        90.7.0.0 [20/0] via 192.168.100.2, 15:02:50
B        90.8.0.0 [20/0] via 192.168.100.2, 15:02:50
B        90.9.0.0 [20/0] via 192.168.100.2, 15:02:50
B        90.10.0.0 [20/0] via 192.168.100.2, 15:02:50
 --More-- B        90.11.0.0 [20/0] via 192.168.100.2, 15:02:50
      192.168.100.0/24 is variably subnetted, 2 subnets, 2 masks
C        192.168.100.0/24 is directly connected, FastEthernet0/0
L        192.168.100.1/32 is directly connected, FastEthernet0/0
R1>

..................THIS IS THE HOST IP ADDRESS...................
192.168.100.2

R2>show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       + - replicated route, % - next hop override

Gateway of last resort is not set

      90.0.0.0/24 is subnetted, 11 subnets
S        90.1.0.0 is directly connected, Null0
S        90.2.0.0 is directly connected, Null0
S        90.3.0.0 is directly connected, Null0
S        90.4.0.0 is directly connected, Null0
S        90.5.0.0 is directly connected, Null0
S        90.6.0.0 is directly connected, Null0
S        90.7.0.0 is directly connected, Null0
S        90.8.0.0 is directly connected, Null0
S        90.9.0.0 is directly connected, Null0
S        90.10.0.0 is directly connected, Null0
 --More-- S        90.11.0.0 is directly connected, Null0
      192.168.100.0/24 is variably subnetted, 2 subnets, 2 masks
C        192.168.100.0/24 is directly connected, FastEthernet0/0
L        192.168.100.2/32 is directly connected, FastEthernet0/0
R2>

..................THIS IS THE HOST IP ADDRESS...................
192.168.100.3

R3>show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       + - replicated route, % - next hop override

Gateway of last resort is not set

      192.168.100.0/24 is variably subnetted, 2 subnets, 2 masks
C        192.168.100.0/24 is directly connected, FastEthernet0/0
L        192.168.100.3/32 is directly connected, FastEthernet0/0
R3> 

这是我得到的 CSV 中的结果:

 protocol,network,mask,AD,nextHop,interface,time
 B,90.1.0.0,,[20/0],192.168.100.2,,02:47:13
 B,90.2.0.0,,[20/0],192.168.100.2,,02:47:13
 B,90.3.0.0,,[20/0],192.168.100.2,,02:47:13
 B,90.4.0.0,,[20/0],192.168.100.2,,02:47:13
 B,90.5.0.0,,[20/0],192.168.100.2,,02:47:13
 B,90.6.0.0,,[20/0],192.168.100.2,,02:47:13
 B,90.7.0.0,,[20/0],192.168.100.2,,02:47:13
 B,90.8.0.0,,[20/0],192.168.100.2,,02:47:13
 B,90.9.0.0,,[20/0],192.168.100.2,,02:47:13
 B,90.10.0.0,,[20/0],192.168.100.2,,02:47:13
 B,90.11.0.0,,[20/0],192.168.100.2,,02:47:13 
 C,192.168.100.0,24,,is directly connected,FastEthernet0/0, 
 L,192.168.100.1,32,,is directly connected,FastEthernet0/0, 
 S,90.1.0.0,,,is directly connected,Null0,
 S,90.2.0.0,,,is directly connected,Null0, 
 S,90.3.0.0,,,is directly connected,Null0, 
 S,90.4.0.0,,,is directly connected,Null0,
 S,90.5.0.0,,,is directly connected,Null0, 
 S,90.6.0.0,,,is directly connected,Null0, 
 S,90.7.0.0,,,is directly connected,Null0,
 S,90.8.0.0,,,is directly connected,Null0, 
 S,90.9.0.0,,,is directly connected,Null0, 
 S,90.10.0.0,,,is directly connected,Null0,
 S,90.11.0.0,,,is directly connected,Null0, 
 C,192.168.100.0,24,,is directly connected,FastEthernet0/0, 
 L,192.168.100.2,32,,is directly connected,FastEthernet0/0, 
 C,192.168.100.0,24,,is directly connected,FastEthernet0/0, 
 L,192.168.100.3,32,,is directly connected,FastEthernet0/0, 
 C,192.168.100.0,24,,is directly connected,FastEthernet0/0, 
 L,192.168.100.3,32,,is directly connected,FastEthernet0/0,

我想要得到的结果:

 device,protocol,network,mask,AD,nextHop,interface,time
 R1,B,90.1.0.0,,[20/0],192.168.100.2,,02:47:13
 R1,B,90.2.0.0,,[20/0],192.168.100.2,,02:47:13
 R1,B,90.3.0.0,,[20/0],192.168.100.2,,02:47:13
 R1,B,90.4.0.0,,[20/0],192.168.100.2,,02:47:13
 R1,B,90.5.0.0,,[20/0],192.168.100.2,,02:47:13
 R1,B,90.6.0.0,,[20/0],192.168.100.2,,02:47:13
 R1,B,90.7.0.0,,[20/0],192.168.100.2,,02:47:13
 R1,B,90.8.0.0,,[20/0],192.168.100.2,,02:47:13
 R1,B,90.9.0.0,,[20/0],192.168.100.2,,02:47:13
 R1,B,90.10.0.0,,[20/0],192.168.100.2,,02:47:13
 R1,B,90.11.0.0,,[20/0],192.168.100.2,,02:47:13 
 R1,C,192.168.100.0,24,,is directly connected,FastEthernet0/0, 
 R1,L,192.168.100.1,32,,is directly connected,FastEthernet0/0, 
 R2,S,90.1.0.0,,,is directly connected,Null0,
 R2,S,90.2.0.0,,,is directly connected,Null0, 
 R2,S,90.3.0.0,,,is directly connected,Null0, 
 R2,S,90.4.0.0,,,is directly connected,Null0,
 R2,S,90.5.0.0,,,is directly connected,Null0, 
 R2,S,90.6.0.0,,,is directly connected,Null0, 
 R2,S,90.7.0.0,,,is directly connected,Null0,
 R2,S,90.8.0.0,,,is directly connected,Null0, 
 R2,S,90.9.0.0,,,is directly connected,Null0, 
 R2,S,90.10.0.0,,,is directly connected,Null0,
 R2,S,90.11.0.0,,,is directly connected,Null0, 
 R2,C,192.168.100.0,24,,is directly connected,FastEthernet0/0, 
 R2,L,192.168.100.2,32,,is directly connected,FastEthernet0/0, 
 R3,C,192.168.100.0,24,,is directly connected,FastEthernet0/0, 
 R3,L,192.168.100.3,32,,is directly connected,FastEthernet0/0, 

这是我的代码

     from collections import ChainMap
     import csv
     import re

     regex_device = re.compile('(?P<Router>^.+)[>#]')

     regex = re.compile('(?P<protocol>\S+) +'
                '(?P<network>\d+\.\d+\.\d+\.\d+)/?'
                '(?P<mask>\d*) +'
                '(?P<AD>\[\d+/\d+\]) +via +'
                '(?P<nextHop>\d+\.\d+\.\d+\.\d+)\,\ +'
                '(?P<interface>\S+\d+/\d+)*'
                '(?P<time>\S+)')


     regex_direktly = re.compile('(?P<protocol>[L|C|S]) +'
                        '(?P<network>\d+\.\d+\.\d+\.\d\d?\d?)/?'
                        '(?P<mask>\d*) +'
                        '(?P<nextHop>.*), +'
                        '(?P<interface>\S+\d/\d+|.*)'
                        '(?P<time>\S*)')

     result = []
     result1 = []

     with open('output_route_table.txt') as data:
         for line in data:
            match = regex_device.search(line)
            if match:
               result1.append(match.groupdict())

     with open('output_route_table.txt') as data:
         for line in data:
            match = regex.search(line)
            if match:
               result.append(match.groupdict())

     with open('output_route_table.txt') as data:
        for line in data:
           match = regex_direktly.search(line)
           if match:
              result.append(match.groupdict())

     with open('output_route_table.csv', 'a') as f:
        writer = csv.DictWriter(f, fieldnames=list(result[0].keys()))
        writer.writeheader()
        for d in result:
            writer.writerow(d)

标签: python-3.6

解决方案


     with open('output_route_table.txt') as data:
         for line in data:
            match = regex_device.search(line)
            if match:
               result1.append(match.groupdict())

     with open('output_route_table.txt') as data:
         for line in data:
            match = regex.search(line)
            if match:
               result.append(match.groupdict())

     with open('output_route_table.txt') as data:
        for line in data:
           match = regex_direktly.search(line)
           if match:
              result.append(match.groupdict())

这部分打开文件 3 次,第一个将路由器名称...刮到您从未使用过的列表中。您只需浏览该文件一次并保存您看到的最后一个路由器(路由属于到目前为止提到的最后一个路由器)。

     last_router = ""
     with open('output_route_table.txt') as data:
         for line in data:
            is_router = regex_device.search(line)
            if is_router:
               last_router = is_router.group('Router') # get the name of the router only
            is_route = regex.search(line) or regex_direktly.search(line) # gets first non-None value or None if all are None
            if is_route:
               result.append({'device': last_router, **is_route.groupdict()})

推荐阅读