如何将交换机SSH返回的端口文本数据转换为Python字典?
问题
通过SSH从交换机获取到端口相关文本数据,需要转换成Python字典数组以便访问监控参数。多次尝试拆分和正则提取都没成功,原始数据格式如下:
Port : 1 Media Type : SF+_SR Vendor Name : VENDORX Part Number : SFP-10G-SR Serial Number : Gxxxxxxxx Wavelength: 850 nm Temp (Celsius) : 37.00 Status : Normal Low Warn Threshold : -40.00 High Warn Threshold : 85.00 Low Alarm Threshold : -50.00 High Alarm Threshold : 100.00 Voltage AUX-1/Vcc (Volts) : 3.27 Status : Normal Low Warn Threshold : 3.10 High Warn Threshold : 3.50 Low Alarm Threshold : 3.00 High Alarm Threshold : 3.60 Tx Power (dBm) : -3.11 Status : Normal Low Warn Threshold : -7.30 High Warn Threshold : 2.00 Low Alarm Threshold : -9.30 High Alarm Threshold : 3.00 Rx Power (dBm) : -4.68 Status : Normal Low Warn Threshold : -11.10 High Warn Threshold : 2.00 Low Alarm Threshold : -13.10 High Alarm Threshold : 3.00 Tx Bias Current (mA): 6.27 Status : Normal Low Warn Threshold : 0.00 High Warn Threshold : 12.00 Low Alarm Threshold : 0.00 High Alarm Threshold : 15.00 Port : 2 Media Type : SF+_SR Vendor Name : VENDORY Part Number : SFP-10G-SR Serial Number : Gxxxxxxxx Wavelength : 850 nm Temp (Celsius) : 37.00 Status : Normal ..... etc - till port 48
期望转换为如下格式的字典数组:
[ { "port": "1", "vendor": "VENDORX", "media_type": "SF+_SR", "part_number": "SFP-10G-SR", "serial_number": "Gxxxxxxxx", "wavelength": "850 nm", "temp": { "value": "37.00", "status": "normal" }, "voltage_aux-1": { "value": "3.27", "status": "normal" }, "tx_power": { "value": "-3.11", "status": "normal" }, "rx_power": { "value": "-4.68", "status": "normal" }, "tx_bias_current": { "value": "6.27", "status": "normal" } }, { "port": "2", "vendor": "VENDORY", "media_type": "SF+_SR", "part_number": "SFP-10G-SR", "serial_number": "Gxxxxxxxx", "wavelength": "850 nm", "temp": { "value": "37.00", "status": "normal" }, # 其他参数省略 } ]
解决方案
可以通过分段处理+正则匹配实现转换,具体思路:
- 按
Port :分割原始文本,得到每个端口的独立数据块 - 对每个端口数据块,用正则精准提取目标参数
- 将提取结果映射到预设的字典结构中,输出符合要求的格式
以下是可直接运行的Python代码:
import re def parse_switch_port_data(raw_text): # 按Port分割文本,过滤空内容块 port_blocks = re.split(r'Port\s*:\s*(\d+)', raw_text.strip()) port_blocks = [block.strip() for block in port_blocks if block.strip()] ports = [] # 每两个元素为一组:端口号 + 对应数据块 for i in range(0, len(port_blocks), 2): port_num = port_blocks[i] block = port_blocks[i+1] if i+1 < len(port_blocks) else "" # 初始化端口数据字典 port_data = { "port": port_num, "vendor": "", "media_type": "", "part_number": "", "serial_number": "", "wavelength": "", "temp": {"value": "", "status": ""}, "voltage_aux-1": {"value": "", "status": ""}, "tx_power": {"value": "", "status": ""}, "rx_power": {"value": "", "status": ""}, "tx_bias_current": {"value": "", "status": ""} } # 提取基础标识参数 port_data["media_type"] = re.search(r'Media Type\s*:\s*(.+)', block).group(1).strip() port_data["vendor"] = re.search(r'Vendor Name\s*:\s*(.+)', block).group(1).strip() port_data["part_number"] = re.search(r'Part Number\s*:\s*(.+)', block).group(1).strip() port_data["serial_number"] = re.search(r'Serial Number\s*:\s*(.+)', block).group(1).strip() port_data["wavelength"] = re.search(r'Wavelength\s*:\s*(.+)', block).group(1).strip() # 提取温度参数 temp_match = re.search(r'Temp \(Celsius\)\s*:\s*([\d.-]+)\s*Status\s*:\s*(\w+)', block) if temp_match: port_data["temp"]["value"] = temp_match.group(1).strip() port_data["temp"]["status"] = temp_match.group(2).strip().lower() # 提取电压参数 voltage_match = re.search(r'Voltage AUX-1/Vcc \(Volts\)\s*:\s*([\d.-]+)\s*Status\s*:\s*(\w+)', block) if voltage_match: port_data["voltage_aux-1"]["value"] = voltage_match.group(1).strip() port_data["voltage_aux-1"]["status"] = voltage_match.group(2).strip().lower() # 提取Tx功率参数 tx_power_match = re.search(r'Tx Power \(dBm\)\s*:\s*([\d.-]+)\s*Status\s*:\s*(\w+)', block) if tx_power_match: port_data["tx_power"]["value"] = tx_power_match.group(1).strip() port_data["tx_power"]["status"] = tx_power_match.group(2).strip().lower() # 提取Rx功率参数 rx_power_match = re.search(r'Rx Power \(dBm\)\s*:\s*([\d.-]+)\s*Status\s*:\s*(\w+)', block) if rx_power_match: port_data["rx_power"]["value"] = rx_power_match.group(1).strip() port_data["rx_power"]["status"] = rx_power_match.group(2).strip().lower() # 提取Tx偏置电流参数 tx_bias_match = re.search(r'Tx Bias Current \(mA\)\s*:\s*([\d.-]+)\s*Status\s*:\s*(\w+)', block) if tx_bias_match: port_data["tx_bias_current"]["value"] = tx_bias_match.group(1).strip() port_data["tx_bias_current"]["status"] = tx_bias_match.group(2).strip().lower() ports.append(port_data) return ports # 测试示例 if __name__ == "__main__": raw_data = """Port : 1 Media Type : SF+_SR Vendor Name : VENDORX Part Number : SFP-10G-SR Serial Number : Gxxxxxxxx Wavelength: 850 nm Temp (Celsius) : 37.00 Status : Normal Low Warn Threshold : -40.00 High Warn Threshold : 85.00 Low Alarm Threshold : -50.00 High Alarm Threshold : 100.00 Voltage AUX-1/Vcc (Volts) : 3.27 Status : Normal Low Warn Threshold : 3.10 High Warn Threshold : 3.50 Low Alarm Threshold : 3.00 High Alarm Threshold : 3.60 Tx Power (dBm) : -3.11 Status : Normal Low Warn Threshold : -7.30 High Warn Threshold : 2.00 Low Alarm Threshold : -9.30 High Alarm Threshold : 3.00 Rx Power (dBm) : -4.68 Status : Normal Low Warn Threshold : -11.10 High Warn Threshold : 2.00 Low Alarm Threshold : -13.10 High Alarm Threshold : 3.00 Tx Bias Current (mA): 6.27 Status : Normal Low Warn Threshold : 0.00 High Warn Threshold : 12.00 Low Alarm Threshold : 0.00 High Alarm Threshold : 15.00 Port : 2 Media Type : SF+_SR Vendor Name : VENDORY Part Number : SFP-10G-SR Serial Number : Gxxxxxxxx Wavelength : 850 nm Temp (Celsius) : 37.00 Status : Normal""" result = parse_switch_port_data(raw_data) import json print(json.dumps(result, indent=2))
代码说明
- 先拆分文本为单个端口的数据块,避免全局匹配的混乱
- 用正则表达式精准定位参数名和对应值,忽略不需要的阈值类参数
- 预设字典结构保证输出格式完全符合需求,同时加入空值判断避免报错
- 状态值统一转为小写,方便后续监控逻辑处理
内容的提问来源于stack exchange,提问作者Erwin van Hoof
相关产品推荐
相关产品推荐

