使用Python对Cisco IOS CDP邻居输出进行排序的技术问询
解决方案:保留表头并按Cisco接口排序
核心思路
- 显式分离CSV表头与数据行,避免表头参与排序导致位置错乱
- 调整原有的接口排序正则函数,适配带空格的接口格式(如
Gig 1/0/7) - 使用
sorted()对数据行排序,通过lambda将每行映射到Local Intrfce字段,再传入排序函数
完整代码示例
import csv import re def cisco_interface_key(interface_str): # 适配带空格的Cisco接口名,比如"Gig 1/0/7"或"GigabitEthernet1/0/11" regex = re.compile(r'(?P<interface_type>[a-zA-Z]+)\s*(?P<port>[\d/]+)') result = regex.search(interface_str) if result: interface_type = result.group("interface_type") port = result.group("port") # 将端口段拆分为整数列表,用于层级排序 port_split = [int(segment) for segment in port.split("/")] port_split.insert(0, interface_type) return tuple(port_split) # 匹配失败时返回空元组,确保异常行排在最前(实际已分离表头,不会触发) return () # 原始CSV格式列表 list2 = [ "Device ID,Local Intrfce,Holdtme,Capability,Platform,Port ID", "MAC1,Gig 1/0/7,144,H P M,IP Phone,Port 1", "MAC3,Gig 1/0/24,155,H P M,IP Phone,Port 1", "MAC2,Gig 1/0/12,133,H P M,IP Phone,Port 1", "MAC8,Gig 1/0/17,143,H P M,IP Phone,Port 1" ] # 解析CSV行 listcsv = list(csv.reader(list2)) # 分离表头和数据行 header = listcsv[0] data_rows = listcsv[1:] # 按Local Intrfce列排序数据行 sorted_data = sorted(data_rows, key=lambda row: cisco_interface_key(row[1])) # 合并表头与排序后的结果 final_sorted_list = [header] + sorted_data # 输出验证 for row in final_sorted_list: print(row)
代码说明
- 正则调整:新正则
(?P<interface_type>[a-zA-Z]+)\s*(?P<port>[\d/]+)能同时匹配两种接口格式:带空格的Gig 1/0/7和不带空格的GigabitEthernet1/0/11,避免端口段带空格导致转整数失败。 - 表头分离:将表头单独提取,只对数据行排序,确保表头始终处于第一行。
- 排序逻辑:lambda表达式
lambda row: cisco_interface_key(row[1])的作用是,对每一行提取第2列(Local Intrfce)作为排序依据,传递给cisco_interface_key生成可排序的元组(如('Gig', 1, 0, 7)),元组会按接口类型、槽位、子槽位、端口号的层级依次排序,和Excel公式的逻辑一致。
为什么natsorted会把表头移到底部?
因为表头的Local Intrfce字符串,在自然排序中比所有Gig开头的接口名靠后(字母L在G之后),所以会被排到数据行的最后。显式分离表头是最可靠的解决方式。
内容的提问来源于stack exchange,提问作者Kinote
相关产品推荐
相关产品推荐

