如何用Python将show ip interface brief输出转为指定表头的规范表格?
问题描述
尝试用textfsm/tabulate工具,将Python执行show ip interface brief命令得到的键值对列表转换为表格,指定表头'intf', 'ipaddr', 'stats', 'proto'后输出不符合预期,期望每个表头对应的字段值依次列在下方。
错误输出(图1)
intf ipaddr stats proto ---------------------------------------------------------------------------------------------------- {'intf': 'GigabitEthernet1/0/21', 'ipaddr': 'unassigned', 'status': 'down', 'proto': 'down'} {'intf': 'GigabitEthernet1/0/22', 'ipaddr': 'unassigned', 'status': 'down', 'proto': 'down'} {'intf': 'GigabitEthernet1/0/23', 'ipaddr': 'unassigned', 'status': 'down', 'proto': 'down'} {'intf': 'GigabitEthernet1/0/24', 'ipaddr': 'unassigned', 'status': 'up', 'proto': 'up'} {'intf': 'GigabitEthernet1/0/25', 'ipaddr': 'unassigned', 'status': 'down', 'proto': 'down'} {'intf': 'GigabitEthernet1/0/26', 'ipaddr': 'unassigned', 'status': 'down', 'proto': 'down'}
代码示例
from netmiko import ConnectHandler import pandas import csv from tabulate import tabulate cisco1 = { "device_type": "cisco_ios", "host": "cisco", "username": "cisco", "password": "cisco", } command = "show ip interface brief" with ConnectHandler(**cisco1) as net_connect: output = net_connect.send_command(command, use_textfsm=True) dataset = [output] #df = pandas.DataFrame(output) #df.to_csv('new.csv', index=True, header=True) headers = ['intf', 'ipaddr', 'stats', 'proto'] print(tabulate(dataset, headers = headers))
解决方法
问题出在两处:
- 数据源格式错误:netmiko的
send_command加use_textfsm=True返回的本身就是一个字典列表(每个字典对应一条接口记录),你把这个列表再套了一层列表,导致tabulate把整个接口列表当成一行的多个元素,格式自然混乱。 - 表头字段不匹配:textfsm返回的字段名是
status,但你表头写的是stats,两者不对应。
修改方案1(直接匹配字段名)
直接用output作为tabulate的数据源,修正表头字段名:
from netmiko import ConnectHandler from tabulate import tabulate cisco1 = { "device_type": "cisco_ios", "host": "cisco", "username": "cisco", "password": "cisco", } command = "show ip interface brief" with ConnectHandler(**cisco1) as net_connect: output = net_connect.send_command(command, use_textfsm=True) # 直接使用textfsm返回的字段名作为表头 headers = ['intf', 'ipaddr', 'status', 'proto'] print(tabulate(output, headers=headers))
修改方案2(映射字段名保留stats表头)
如果坚持要用stats作为表头,可通过列表推导式重命名字段:
from netmiko import ConnectHandler from tabulate import tabulate cisco1 = { "device_type": "cisco_ios", "host": "cisco", "username": "cisco", "password": "cisco", } command = "show ip interface brief" with ConnectHandler(**cisco1) as net_connect: output = net_connect.send_command(command, use_textfsm=True) # 将每个字典中的status字段重命名为stats formatted_output = [ { 'intf': item['intf'], 'ipaddr': item['ipaddr'], 'stats': item['status'], 'proto': item['proto'] } for item in output ] headers = ['intf', 'ipaddr', 'stats', 'proto'] print(tabulate(formatted_output, headers=headers))
内容的提问来源于stack exchange,提问作者Joshua
相关产品推荐
相关产品推荐

