如何使用Ansible访问处理表格文本、提取值实现条件判断?
Ansible解析表格提取数值做状态判定实现方案
核心思路
你拿到的是竖线分隔的固定格式纯文本表格,不需要安装第三方自定义模块,用Ansible自带的过滤器、类型转换功能就能完成文本到结构化数据的转换,之后直接遍历数据做条件判断即可。
完整Playbook示例
- name: 提取Counter Source活跃状态 hosts: localhost gather_facts: false vars: # 原始表格文本,若表格来自命令执行结果,可直接替换为对应寄存器的stdout值 raw_counter_table: | Counter Source | Counter Name | Unit | Min | Max | Average | Last ---------------+-----------------+-------+-------+-------+---------+------- Source1 | GC1 | % | 3.00 | 22.00 | 3.01 | 3.00 Source2 | GC2 | % | 2.00 | 7.00 | 2.95 | 3.00 Source3 | GC3 | % | 2.00 | 12.00 | 3.00 | 3.00 Source4 | GC4 | % | 15.00 | 16.00 | 15.22 | 15.00 Source5 | GC5 | % | 39.00 | 44.00 | 41.32 | 43.00 # 文本预处理:拆分每行、去除首尾空白、过滤掉由-和+组成的表格分隔线行 table_lines: "{{ raw_counter_table.split('\n') | map('trim') | reject('search', '\\+') | list }}" # 提取表头字段,按|拆分后去除空白得到字段名列表 table_headers: "{{ table_lines[0].split('|') | map('trim') | list }}" # 逐行解析数据,转换为[{'字段名': 值, ...}]的结构化字典列表 counter_records: "{{ table_lines[1:] | map('split', '|') | map('map', 'trim') | map('zip', table_headers) | map('map', 'reverse') | map('items2dict') | list }}" tasks: - name: 按规则判定每个数据源的状态 ansible.builtin.set_fact: counter_status: "{{ counter_status | default([]) + [ { 'source': item['Counter Source'], 'average': item['Average'] | float, 'status': '活跃' if (item['Average'] | float) > 0 else '非活跃' } ] }}" loop: "{{ counter_records }}" - name: 打印判定结果 ansible.builtin.debug: msg: "数据源{{ item.source }}的Average值为{{ item.average }},判定为{{ item.status }}状态" loop: "{{ counter_status }}"
关键说明
- 解析逻辑会自动过滤表格首尾的横线装饰行、表头下方的分隔线行,不需要手动清理原始文本。
- 数值比较前会把Average列的字符串值转为浮点数,避免字符串类型比较导致的判断错误。
- 最终生成的
counter_status是结构化列表,后续任务可以直接在when条件中引用状态值做分支逻辑,比如只对活跃数据源执行后续操作时,加判断条件when: item.status == '活跃'即可。 - 如果原始表格来自其他模块的返回结果(比如网络设备API、监控命令输出),只需要替换
raw_counter_table的赋值,其余解析、判断逻辑不需要修改。
示例运行输出
ok: [localhost] => (item={'source': 'Source1', 'average': 3.01, 'status': '活跃'}) => { "msg": "数据源Source1的Average值为3.01,判定为活跃状态" } ok: [localhost] => (item={'source': 'Source2', 'average': 2.95, 'status': '活跃'}) => { "msg": "数据源Source2的Average值为2.95,判定为活跃状态" } ok: [localhost] => (item={'source': 'Source3', 'average': 3.0, 'status': '活跃'}) => { "msg": "数据源Source3的Average值为3.0,判定为活跃状态" } ok: [localhost] => (item={'source': 'Source4', 'average': 15.22, 'status': '活跃'}) => { "msg": "数据源Source4的Average值为15.22,判定为活跃状态" } ok: [localhost] => (item={'source': 'Source5', 'average': 41.32, 'status': '活跃'}) => { "msg": "数据源Source5的Average值为41.32,判定为活跃状态" }
如果某条数据源的Average值为0,会自动判定为非活跃状态,无需调整逻辑。
内容的提问来源于stack exchange,提问作者Aditya Siddarth
相关产品推荐
相关产品推荐

