将输出 txt "show ip route" 解析为 csv

Parsing output txt "show ip route" to csv

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

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

..................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)
     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()})