1
x       y           z                  a            b               c
------ ----------- ------------------ ------------ --------------- ------------
4000   4000       No ID              Hun0/0/12       1.1.1.1           0           
       4001       No ID              Hun0/0/12       1.1.1.1      0

Used FSM

Value x((\d+)?)
Value y(\w+)
Value z(No ID|[\w\./:]+)
Value a([\w/\.]+)
Value b[\d\./:]+)
Value c(\d+)

Start
  ^${x}\s+${y}\s+${z}\s+(${a}\s+)?${b}\s+${c} -> Record


This is the ouput i am getting with above fsm:

['4000', '4000', 'No ID', 'Hun0/0/12', '1.1.1.1', '0']
['', '4001', 'No ID', 'Hun0/0/12', '1.1.1.1', '0']

Desired output is as follows:

['4000', '4000', 'No ID', 'Hun0/0/12', '1.1.1.1', '0']
['4000', '4001', 'No ID', 'Hun0/0/12', '1.1.1.1', '0']

Need some idea on this.Here, i wanted all the values to be string only, not List.

bell
  • 11
  • 2
  • The value `4000` is not there in the input (for the 2nd line), so how should the fsm know you want it there? The parser allows multi-line records but you already terminate the record after the first line (so all variable assignments are reset) and the empty x field on the second line matches `(\d+)?` (because of the `?`) so it will assign the empty string to `x` in any case. – Marijn Aug 04 '23 at 13:13
  • Okay, how can i fix this with multi line recording ?? – bell Aug 04 '23 at 13:42
  • I finished my answer that I posted too early by mistake. – Marijn Aug 04 '23 at 14:00

1 Answers1

0

In order to store a value from one line to the next you can use the Filldown value option. However, this only works if the value is on its own line in the template. If it is part of the rest of the matching pattern then the full pattern needs to be matched for the second line, including the value that is not there in the second line.

If you put the filldown value on a separate line in the template, then you need to use a -> Continue statement at the end of the template line. Then the filldown value can be skipped on the second input line (and the old value will be reused), while the rest of the template can still be matched (both for the first and the second input line) by the second line in the template.

Because Continue does not 'see' the previous match (for x) you need to match it again, but then as a unnamed regex inside of the template rule (because the value assignment has already occurred). Note the \d* in the template below instead of \d+, otherwise the second line will not match (as it has no digits at that position).

One issue with Filldown values is that they are retained until the end of the file (unless they are reset), so after the input is finished a line ending may cause an additional record with only the Filldown value and all other fields as an empty string. To prevent this you can require one or more of the other fields. Of course for this to work the field(s) must actually be present in all records.

Template:

Value Filldown x (\d+)
Value Required y (\w+)
Value z (No ID|[\w\./:]+)
Value a ([\w/\.]+)
Value b ([\d\./:]+)
Value c (\d+)

Start
  ^${x}\s+ -> Continue
  ^\d*\s+${y}\s+${z}\s+(${a}\s+)?${b}\s+${c} -> Record

Python code:

import textfsm
raw_data = """x       y           z          a            b               c
------ ----------- ------------------ ------------ --------------- ------------
4000   4000       No ID              Hun0/0/12       1.1.1.1        0           
       4001       No ID              Hun0/0/12       1.1.1.1        0
"""
template = open("template.txt")
re_table = textfsm.TextFSM(template)
template.close()
print(re_table.ParseText(raw_data))

Result:

[['4000', '4000', 'No ID', 'Hun0/0/12', '1.1.1.1', '0'],
['4000', '4001', 'No ID', 'Hun0/0/12', '1.1.1.1', '0']]
Marijn
  • 1,640
  • 14
  • 24