如何从Ansible playbook的stdout_lines中提取可用MB数值?
从Ansible stdout_lines提取剩余磁盘空间数值的解决方案
问题场景
需要从Ansible任务返回的stdout_lines中提取剩余磁盘空间的MB数值(如示例中的589.6),作为后续playbook流程的判断依据。
任务返回的输出如下:
ok: [Host1] => { "changed": false, "invocation": { "module_args": { "commands": [ "show file systems | inc flash:" ], "interval": 1, "match": "all", "retries": 10, "wait_for": null } }, "stdout": [ "* 1707192 (1.6 GB) 603744 (589.6 MB) flash rw flash:" ], "stdout_lines": [ [ "* 1707192 (1.6 GB) 603744 (589.6 MB) flash rw flash:" ] ] }
尝试使用以下语句提取时,得到空输出:
- set_fact: my_var: "{{ disk_space.stdout_lines | regex_findall('\b([0-9]{1,4}\.\d+)\s+MB.*flash:$') }}"
空输出结果:
ok: [Host1] => { "ansible_facts": { "my_var": [] }, "changed": false }
解决方法
问题分析
- 嵌套列表未处理:
stdout_lines的结构是嵌套列表([[目标字符串]]),直接对其使用正则过滤器无法匹配到有效内容。 - 正则表达式匹配逻辑错误:原正则的边界符
\b、末尾匹配规则.*flash:$与实际字符串格式不匹配,导致无法捕获目标数值。
正确的提取代码
可以通过两种方式实现正确提取:
方式1:使用flatten扁平化列表
- set_fact: my_var: "{{ disk_space.stdout_lines | flatten | regex_findall('\\((\\d+\\.\\d+) MB\\)') | first }}"
方式2:直接索引嵌套列表
- set_fact: my_var: "{{ disk_space.stdout_lines[0][0] | regex_findall('\\((\\d+\\.\\d+) MB\\)') | first }}"
代码说明
- 处理嵌套结构:
flatten过滤器将嵌套的二维列表转为一维列表,直接暴露目标字符串;[0][0]则通过索引直接定位到嵌套列表中的目标行字符串。
- 正则表达式:
\((\d+\.\d+) MB\)精准匹配(589.6 MB)格式,其中(\d+\.\d+)作为捕获组提取带小数点的数值。 - 提取单个值:
regex_findall返回匹配到的结果列表,first过滤器取出第一个(也是唯一的)数值,最终得到字符串形式的589.6。
扩展:转为数值类型
如果需要将提取的字符串转为浮点型数值用于后续数值判断,可添加| float过滤器:
- set_fact: my_var: "{{ disk_space.stdout_lines | flatten | regex_findall('\\((\\d+\\.\\d+) MB\\)') | first | float }}"
内容的提问来源于stack exchange,提问作者PraveenPrasannan
相关产品推荐
相关产品推荐

