TextFSM
TextFSM is a Python module that implements a template-based state machine for parsing semi-structured text into Python tables. Originally developed by Google, it's widely used for extracting structured data from command-line interface (CLI) output of network devices. The library is currently at version 2.1.0 and has a sporadic but active release cadence, focusing on fixes and improvements.
Warnings
- gotcha TextFSM templates use a strict Domain Specific Language (DSL). Incorrect `Value` definitions (e.g., missing regex capture groups, invalid options like `Filldown` without a match), improper `Start` state definitions, or incorrect indentation/blank lines can lead to parsing failures or `textfsm.TextFSMError` exceptions. An empty line after `Value` definitions signals the end of that section.
- gotcha Misunderstanding the `Required` option vs. `Filldown`/`Fillup` can lead to unexpected output. `Required` ensures a record is only emitted if the value is present. `Filldown` propagates the last matched value downwards, while `Fillup` propagates the first matched value upwards to fill preceding empty fields.
- deprecated While PyPI tags list `Python 2, Python 3` compatibility, modern development and usage of TextFSM (and its ecosystem like `ntc-templates`) strongly recommend Python 3. Older versions like `textfsm==0.4.1` explicitly supported Python 2.x and Python 3.x, but ongoing maintenance primarily targets Python 3 environments.
- breaking The `clitable` module, which provides the `CliTable` utility for loading TextFSM templates from directories, might have had changes in its import path or internal workings in the past. This could lead to `ImportError: cannot import name 'clitable' from 'textfsm'` in projects that directly accessed it.
Install
-
pip install textfsm
Imports
- TextFSM
import textfsm
Quickstart
import textfsm
import io
# Example template string (equivalent to a .textfsm file)
template_string = '''
Value Interface (\S+)
Value IP_Address (\S+)
Value Status (\S+)
Value Protocol (\S+)
Start
^Interface\s+IP-Address\s+Status\s+Protocol\s*$$
^${Interface}\s+${IP_Address}\s+${Status}\s+${Protocol} -> Record
'''
# Example raw text output to parse
raw_text_data = '''
Interface IP-Address Status Protocol
GigabitEthernet0/1 192.168.1.1 up up
GigabitEthernet0/2 10.0.0.1 up up
Loopback0 unassigned up down
'''
# Open the template (using io.StringIO for a string, normally a file path)
with io.StringIO(template_string) as template_file:
# Create a TextFSM object
fsm = textfsm.TextFSM(template_file)
# Parse the raw text data
parsed_data = fsm.ParseText(raw_text_data)
# Print headers and data
print(fsm.header)
for row in parsed_data:
print(row)
# Expected output:
# ['Interface', 'IP_Address', 'Status', 'Protocol']
# ['GigabitEthernet0/1', '192.168.1.1', 'up', 'up']
# ['GigabitEthernet0/2', '10.0.0.1', 'up', 'up']
# ['Loopback0', 'unassigned', 'up', 'down']