TEXTFSM Weird Behaviour

60 views Asked by At

I have the following CLI output i need to parse:


 Status and Counters - General System Information

  System Name        : Switch-Name-2
  System Contact     :
  System Location    :

  MAC Age Time (sec) : 300

  Time Zone          : 0
  Daylight Time Rule : None

  Software revision  : WC.16.10.0009        Base MAC Addr      : ******-******

  ROM Version        : WC.16.01.0008        Serial Number      : **********

  Up Time            : 371 days             Memory   - Total   : 339,329,536
  CPU Util (%)       : 9                               Free    : 217,292,368

  IP Mgmt  - Pkts Rx : 7,218,420            Packet   - Total   : 6600
             Pkts Tx : 6,911,783            Buffers    Free    : 4281
                                                       Lowest  : 4161
                                                       Missed  : 0

And i thought i had done a good job with the following TEXTFSM template:

Value Uptime (\d+\s\S+)
Value CPU (\d+)
Value MemTotal (\S+)
Value MemFree (\S+)

Start
  ^${Uptime}
  ^\)\s+:\s${CPU}
  ^Memory\s+-\sTotal\s+:\s${MemTotal}
  ^\d+\s+Free\s+:\s+${MemFree} -> Record

However it always returns with no outputs :S

I'm pretty new to TEXTFSM but at the end of the day its just REGEXs.

I would expect the output to be the Uptime, CPU %, Memory Total and Memory Free

2

There are 2 answers

0
furas On BEST ANSWER

This works for me

Value Uptime (\d+\s\S+)
Value CPU (\d+)
Value MemTotal (\S+)
Value MemFree (\S+)

Start
  ^Up\sTime\s+:\s${Uptime}\s+Memory\s+\-\sTotal\s+:\s+${MemTotal}
  ^CPU\sUtil\s\(\%\)\s+:\s${CPU}\s+Free\s+:\s+${MemFree} -> Record

First: you forgot Up Time : for fist value.
Second: some values are in one line so they may have to be in the same line in template.


BTW: ^ in template means beginning of line so you can't use ^ to search element which is not at the beginning of line. You can't use ^${Uptime} to search value because there is text Up Time : before value. You can't use ^\) because ) doesn't start line. You would have to add .* to catch all other values before )

And it seems - has special meaning in template so it needs \-


Code which I used for tests

import textfsm

template_fh = open('template.txt')     # without `.read()` to get `file handler`
data        = open('data.txt').read()  # with `.read()` to get `text` 

template = textfsm.TextFSM(template_fh)
data     = template.ParseText(data)

print( ' | '.join(template.header) )
# Each row of the table.
for row in data:
  print( ' | '.join(row) )

Result:

Uptime | CPU | MemTotal | MemFree
371 days | 9 | 339,329,536 | 217,292,368

EDIT:

The same code with data and template directly in code.
I use io.StringIO() to create file-like object.
This way everyone can simply copy and run code.

import textfsm
import io

# use `io.String` to create `file-like` object
template_fh = io.StringIO('''Value Uptime (\d+\s\S+)
Value CPU (\d+)
Value MemTotal (\S+)
Value MemFree (\S+)

Start
  ^Up\sTime\s+:\s${Uptime}\s+Memory\s+\-\sTotal\s+:\s+${MemTotal}
  ^CPU\sUtil\s\(\%\)\s+:\s${CPU}\s+Free\s+:\s+${MemFree} -> Record
''')

data = '''Status and Counters - General System Information

System Name        : Switch-Name-2
System Contact     :
System Location    :

MAC Age Time (sec) : 300

Time Zone          : 0
Daylight Time Rule : None

Software revision  : WC.16.10.0009        Base MAC Addr      : ******-******

ROM Version        : WC.16.01.0008        Serial Number      : **********

Up Time            : 371 days             Memory   - Total   : 339,329,536
CPU Util (%)       : 9                               Free    : 217,292,368

IP Mgmt  - Pkts Rx : 7,218,420            Packet   - Total   : 6600
           Pkts Tx : 6,911,783            Buffers    Free    : 4281
                                                     Lowest  : 4161
                                                     Missed  : 0
'''

template = textfsm.TextFSM(template_fh)
data     = template.ParseText(data)

print( ' | '.join(template.header) )
# Each row of the table.
for row in data:
  print( ' | '.join(row) )
0
Reilas On

Try a capture pattern.

(?:Up Time|Memory.+?Total|CPU Util|(?<=\d)\s+?Free).+?:.+?([\d,]+)
371
339,329,536
9
217,292,368