Google开源库Textfsm使用文档(中文翻译)

TextFSM

介绍

TextFSM 是一个 Python 模块,实现了一个基于状态机的模板,用来解析半格式化的文本。

最初开发的目的是允许程序化地获取来源于 CLI 驱动设备的输出信息,例如网络路由器或交换机,不过它可以被用作任何这种类型的文本输出。

这个引擎需要两个输入:一个模板文件和文本输入(比如 CLI 设备的命令回显),并返回一个表,其中记录了从文本中解析出的数据。

每个独特结构的文本输入都需要一个模板文件。本文提供了一些代码示例,并鼓励用户独立开发。

通过开发一个模板文件池,脚本可以调用 TextFSM 从各种来源中解析出有用的信息。它同样有可能在相同的数据上用不同的模板,来制造出不同的表格(或视图)。

详细说明

使用库

快速入门示例:

# 通过 FSM 运行文本
# 这个'template'参数是一个文件对象,'raw_text_data'参数是一个字符串
re_table = textfsm.TextFSM(template)
data = re_table.ParseText(raw_text_data)

# 以 CSV 的形式来展示结果
# 打印第一列的标题
print( ', '.join(re_table.header) )
# 打印表的每一行数据
for row in data:
    print( ', '.join(row) )

这个库可以通过上面的方式执行,也可以直接执行,用于检查模板语法,并将预计的输出和输入相比较:

parser.py [--help] template [input_file [output_file]]

如果安装为软件包,它将会在 Python 的相关版本文件夹下:

usr/local/lib/pythonx.y/dist-packages/textfsm/parser.py

数据形式

FSM 的核心目的是从文本数据中提取关键的数据,并将其放入一个表格形式中。

下面给出一个原始输入数据,我们也许会对线卡状态和温度感兴趣:

Routing Engine status:
  Slot 0:
    Current state                  Master
    Election priority              Master (default)
    Temperature                 39 degrees C / 102 degrees F
    CPU temperature             55 degrees C / 131 degrees F
    DRAM                      2048 MB
    Memory utilization          76 percent
    CPU utilization:
      User                      95 percent
      Background                 0 percent
      Kernel                     4 percent
      Interrupt                  1 percent
      Idle                       0 percent
    Model                          RE-4.0
    Serial ID                      xxxxxxxxxxxx
    Start time                     2008-04-10 20:32:25 PDT
    Uptime                         180 days, 22 hours, 45 minutes, 20 seconds
    Load averages:                 1 minute   5 minute  15 minute
                                       0.96       1.03       1.03
Routing Engine status:
  Slot 1:
    Current state                  Backup
    Election priority              Backup
    Temperature                 30 degrees C / 86 degrees F
    CPU temperature             31 degrees C / 87 degrees F
    DRAM                      2048 MB
    Memory utilization          14 percent
    CPU utilization:
      User                       0 percent
      Background                 0 percent
      Kernel                     0 percent
      Interrupt                  1 percent
      Idle                      99 percent
    Model                          RE-4.0
    Serial ID                      xxxxxxxxxxxx
    Start time                     2008-01-22 07:32:10 PST
    Uptime                         260 days, 10 hours, 45 minutes, 39 seconds

使用一个恰当的模板将此文本输入应用于 FSM,结果返回一个表格形式,其中线卡和相关数据作为记录的字段关联在一起。

Slot 型号 内存 状态 温度 CPU温度
0 RE-4.0 2048 Master 39 55
1 RE-4.0 2048 Backup 30 31

模板文件

模板文件描述了 FSM 应当如何解析数据,不同的文本输入形式需要单独的模板。比如,解析路由器命令的输出,通常每一个命令都需要一个模板

下面是一个完整的模板示例。在这个示例中,展示了如何处理路由器上的 'show chassis routing-engine' 命令的输出:

# # Chassis value will be null for single chassis routers.
Value Filldown Chassis (.cc.?-re.)
Value Required Slot (\d+)
Value State (\w+)
Value Temp (\d+)
Value CPUTemp (\d+)
Value DRAM (\d+)
Value Model (\S+)

# FSM 总是先在'start'状态启动
Start
  ^${Chassis}
  # Record current values and change state.
  # No record will be output on first pass as 'Slot' is 'Required' but empty.
  ^Routing Engine status: -> Record RESlot

# 状态转换是非必须的,但是这有助于示例
RESlot
  ^\s+Slot\s+${Slot}
  ^\s+Current state\s+${State}
  ^\s+Temperature\s+${Temp} degrees
  ^\s+CPU temperature\s+${CPUTemp} degrees
  ^\s+DRAM\s+${DRAM} MB
  # Transition back to Start state.
  ^\s+Model\s+${Model} -> Start

# 一个隐式的 EOF 状态输出,会执行最后一次记录

模板文件由两个顶级部分组成

  • Value 的定义,描述了要提取的数据列;

  • 一个或更多的状态的定义,描述了解析数据时引擎的多种状态。

如果一行以任意数量的空格开头再跟一个井号(即与正则表达式^\s*#匹配),则被认为是一个注释。

Value 定义

一行或多行的 Value 被用作描述每一个列,并且它将会出现在作为结果的表格中。所有的 Value 必须出现在状态定义之前,并且行之间必须相邻(除了被注释分隔)。

每行 Value 都是下面这种格式:

Value [option[,option...]] name regex
关键字 类型 描述
Value 关键字 表示开始定义Value,必填项。
option 标志位。逗号分隔,不能有空格 关于Value的额外选项。可以是以下一项或多项:
Filldown 先前匹配的值会保留到之后的记录(除非显式清除或再次匹配)。换句话说, 最近的匹配值会被复制到新的行,除非再次匹配。
Key 宣告字段的内容作为行的唯一标识符。
Required 仅当此值匹配时,记录(行)才会保存到表中。
List 表示这个值是一个列表,增加到每一次匹配(否则通常来说每次匹配都将覆写那一个行的值)。
Fillup 类似Filldown,但是向上填充,直到它找到一个非空的记录。不能与RequiredList兼容。
name 名称 用于Value的命名, 最终将作为列名。不能用已存在的option的名称来命名。
regex 正则表达式 一个正则表达式,用于匹配Value,这个正则表达式必须包含在括号中。

状态定义

Value 定义之后,开始描述状态定义。每个状态定义之间要用一个空行分开。第一行是一个由字母或数字组成的状态名,随后是一连串的 rule(规则)

一个完整的状态定义是下面这种格式:

StateName
 ^rule
 ^rule
 ...

多行状态定义之间至少用一个空行分开。多个规则要写在连续的行上(不能有空行),并紧跟在状态名之后,且规则前面必须用一个或两个空格缩进,加上一个插入符号^来开头。

启动的时候,FSM 将开始于 Start 状态。输入行仅能和当前状态的规则相比较,但是一个匹配的输入行可以触发一个状态转换,来转换到新的状态。
操作会逐行继续,直到遇到 EOF 状态或当前状态转换到 End 状态。

保留状态

FSM 开始于 Start 状态,所以这个标签是强制的,模板失去它将不能解析。

如果输入达到了 EOF 状态,那么 EOF 状态将会执行。这是一个隐式的状态,看起来像是这样:

EOF
  ^.* -> Record

EOF 在返回之前记录当前行,可以去覆盖这个行为:显式定义一个空的 EOF 状态,像是这样:

EOF

End 状态是保留状态,并会终止输入行的进程,且不执行 EOF 状态。

状态规则

每个状态定义由一个或多个的规则组成。FSM 从输入缓冲区读取一行,依次对照每个规则进行检测(从当前状态的第一条规则开始)。如果一个规则匹配了这行内容,那么 action(行为) 会执行,并重复进程(从第一个状态开始)。

规则是下面这种格式:

^regex [-> action]

regex 是一个正则表达式,用于和输入行相匹配。这个匹配会从输入行的开头执行,所以尽管插入符号(^)是隐式的,但需要在语法上显式指定,以提醒此行为。

正则表达式中可能包含零个或更多的 Value 描述符Value 描述符采用这两种格式 $ValueName${ValueName}(推荐后者的格式),表示从 Value 中取值。关联 Value 的正则表达式会被替换到规则的正则表达式中,并且如果输入行匹配了规则,与 Value 匹配的文本会赋值给当前记录

指定行的结束(EOL)需要使用两个美元符号$$,当 Value 替换的时候将被替换为一个美元符号。

比如采用下面这个模板:

Value Interface (\S+)

Start
  ^Interface ${Interface} is up

当开始解析这个模板的时候,FSM 会扩展规则的正则表达式为:

^Interface (\S+) is up

如果通过这个规则解析下面的输入行,这个Interface的值会被赋予一个值:GigabitEthernet1/10

Interface GigabitEthernet1/10 is up.

可以将多个 Value描述符 放到一个规则的正则表达式中。但是所有额外的正则表达式必须全部匹配,才能将所有的值分配到记录

规则行为

在正则表达式之后,可能需要描述行为。由符号->分隔,格式是这样:'A.B C'

行为被分解为三个可选部分:A) 行行为,在输入行上的行为。B) 记录行为,对目前为止收集到的值执行的行为。C) 状态转换

如果没有描述行为,也就是说没有->符号,那么默认的隐式行为Next.NoRecord

行行为

行为 描述
Next 结束输入行,读取下一行并从 start 状态再次开始匹配。如果没有指定行行为,那么这会是默认行为
Continue 保持当前行,并不再从状态的第一个规则匹配。程序将继续处理规则,就好像匹配没有发生过(值的分配仍会发生)。

记录行为

行行为之后是可选的记录行为,它们之间用一个英文句号分隔.

行为 描述
NoRecord 什么也不做。这是默认行为,如果没有指定记录行为
Record 将目前为止已经收集到的值作为一行记录添加到返回数据中。非 Filldown 的值会被清除。注意: 如果这里有任意未赋值的 Required 值,则记录(行)将不会被添加到返回数据中。
Clear 清除非 Filldown 的值
Clearall 清除所有值

仅当同时指定了行和记录行为时,才需要点.分隔符。如果一个或两个行为被保留为隐式默认值,那么这个点可以忽略。例如:NextNext.NoRecordNoRecord,它们之间是等价的。

状态转换

这个行为是可选的,在行行为记录行为后面添加一个空格和一个新的状态名,来表示转换到新的状态。这个新的状态必须是一个保留状态或一个在模板中有效定义的状态。

匹配后,在正常执行所有行为后,从输入中读取下一行,然后将当前状态更改为新状态,并在此新状态中继续处理进程。

注意:Continue 行为不会接受状态转换。这会确保状态机是无环的。

错误行为

这里有一个特殊的行为 Error。这个行为将终结所有进程并且将不会返回到表格,丢弃到目前为止收集的所有的行,并抛出一个异常。

这个行为的语法是这样的:

^regex -> Error [word|"string"]
posted @ 2023-07-25 23:27  Désiré  阅读(992)  评论(0编辑  收藏  举报