1.TextFSM.py文件
from textfsm import TextFSM
if __name__ == '__main__':
with open('show_version.log', 'r', encoding='utf8') as f:
dev_text = f.read()
template = TextFSM(open('show_version_easy.textfsm'))
version_info = template.ParseTextToDicts(dev_text)
print(version_info)
2.show_version.log文件
output = '''
show vlan
VLAN Name status Ports
1 default active Eth1/1,Eth1/2,Eth1/3
Eth1/5,Eth1/6,Eth1/7
2 VLAN0002 active Po100,Eth1/49,Eth1/50
3 VLAN0003 active Po100,Eth1/ 49,Eth1/50
4 VLAN0004 active Po100,Eth1/49,Eth1/50
5 VLAN0005 active Po100,Eth1/49,Eth1/50
6 VLAN0006 active Po100,Eth1/49,Eth1/50
7 VLAN0007 active Po100,Eth1/49,Eth1/50
8 VLAN0008 active Po100,Eth1/49,Eth1/50
'''
3.show_version_easy.textfsm文件
Value VLAN_ID (\d+)
Value NAME (\w+)
Value STATUS (\w+)
Start
^${VLAN_ID}\s+${NAME}\s+${STATUS}\s+ -> Record
详细解释:
(1)在show_version_easy.textfsm中,我们使用Value语句来定义变量,这里定义了3个变量,分别是VLAN_ID、NAME和STATUS。
Value VLAN_ID (\d+)
Value NAME (\w+)
Value STATUS (\w+)
(2)每个变量后面都有它自己对应的正则表达式模式(Pattern),这些模式写在括号()中。比如变量VLAN_ID顾名思义是要去匹配VLAN的ID的,所以它后面的正则表达式模式写为(\d+)。在以前讲过,\d这个特殊序列用来匹配数字,后面的+用来做贪婪匹配。同理,变量NAME是用来匹配VLAN的名称的,因为这里VLAN的名称掺杂了字母和数字,比如VLAN0002,所以它的正则表达式模式写为(\w+)。\w这个特殊序列用来匹配字母或数字,后面的+用来做贪婪匹配。同理,变量STATUS(\w+)用来匹配VLAN状态,VLAN状态会有active和inactive之分。
(3)在定义好变量后,我们使用Start语句来定义匹配规则,匹配规则由正则表达式的模式及变量名组成。
Start
^${VLAN_ID}\s+${NAME}\s+${STATUS}\s+ ->Record
(4)Start语句后面必须以正则表达式^开头。^是正则表达式中的一种特殊字符,用于匹配输入字符串的开始位置,注意紧随其后的$不是正则表达式里的$,它的作用不是用来匹配输入字符串的结尾位置,而是用来调用我们之前设置好的VLAN_ID并匹配该变量。注意,在TextFSM中调用变量时可以用大括号{},写成${VLAN_ID},也可以不用,写成$VLAN_ID,但是TextFSM官方推荐使用大括号。VLAN_ID对应的正则表达式恰巧是\d+,这样就匹配到了1、2、3、4、5、6、7、8这些VLAN_ID,而后面的\s+则表示匹配1、2、3、4、5、6、7、8后面的空白字符(\s这个特殊序列用来匹配空白字符)。
(5)同理,我们调用变量NAME,它对应的正则表达式模式为\w+,该特殊序列用来匹配show vlan命令回显内容中的default、VLAN0002、VLAN0003、…、VLAN0008等内容,而后面的\s则用来匹配之后所有的空白字符。
(6)变量{STATUS}也一样,它对应的\w+用来匹配active和inactive这两种VLAN状态(例子中给出的show vlan的回显内容中没有inactive,但是不影响理解)以及后面的空白字符。最后用-> Record来结束TextFSM的匹配规则。
运行结果
[{'VLAN_ID': '1', 'NAME': 'default', 'STATUS': 'active'}, {'VLAN_ID': '2', 'NAME': 'VLAN0002', 'STATUS': 'active'}, {'VLAN_ID': '3', 'NAME': 'VLAN0003', 'STATUS': 'active'}, {'VLAN_ID': '4', 'NAME': 'VLAN0004', 'STATUS': 'active'}, {'VLAN_ID': '5', 'NAME': 'VLAN0005', 'STATUS': 'active'}, {'VLAN_ID': '6', 'NAME': 'VLAN0006', 'STATUS': 'active'}, {'VLAN_ID': '7', 'NAME': 'VLAN0007', 'STATUS': 'active'}, {'VLAN_ID': '8', 'NAME': 'VLAN0008', 'STATUS': 'active'}]
[{'VLAN_ID': '1', 'NAME': 'default', 'STATUS': 'active'}, {'VLAN_ID': '2', 'NAME': 'VLAN0002', 'STATUS': 'active'}, {'VLAN_ID': '3', 'NAME': 'VLAN0003', 'STATUS': 'active'}, {'VLAN_ID': '4', 'NAME': 'VLAN0004', 'STATUS': 'active'}, {'VLAN_ID': '5', 'NAME': 'VLAN0005', 'STATUS': 'active'}, {'VLAN_ID': '6', 'NAME': 'VLAN0006', 'STATUS': 'active'}, {'VLAN_ID': '7', 'NAME': 'VLAN0007', 'STATUS': 'active'}, {'VLAN_ID': '8', 'NAME': 'VLAN0008', 'STATUS': 'active'}]