Ansible regex_search处理多行字符串时仅提取指定行的问题
解决Ansible regex_search匹配多余内容的问题
你的stdout内容是这样的:
"msg": [ "--------------------------------------------------------------------------------\nHostname : switch1\nChassis Type : 7144-d\nPart Number : 3HE1RA01\nSerial Number : 630943\nSystem HW MAC Address: 18:C3:ff:ff:ff:F5\nSoftware Version : v22.1.1\nBuild Number : 90-g4b19af2d95\nArchitecture : x86_64\nLast Booted : 2023-01-09T19:55:26.679Z\nTotal Memory : 15987484 kB\nFree Memory : 13054218 kB\n--------------------------------------------------------------------------------" ]
你写了这段Playbook想单独提取Software Version : v22.1.1这一行:
- name: Get version set_fact: version: "{{ show_version.stdout | regex_search('Software Version.*') }}"
但结果却把这行后面的所有内容都带进来了:
{ "version": "Software Version : v22.1.1\\nBuild Number : 90-g4b19af2d95\\nArchitecture : x86_64\\nLast Booted : 2023-01-09T19:55:26.679Z\\nTotal Memory : 15987484 kB\\nFree Memory : 13054218 kB\\n--------------------------------------------------------------------------------']" }
问题出在哪
- 你用的
.*是贪婪匹配规则,会尽可能往后匹配字符,直到整个字符串结束。 - 你的stdout里的换行是以
\\n转义字符串形式存储的(不是真正的换行符),正则中的.可以匹配\和n这两个普通字符,所以.*会一路匹配到字符串末尾。 - 你误解了单行模式的作用:单行模式是让
.能匹配真正的换行符,和当前遇到的问题无关。
怎么改
有两种简单方法可以只拿到目标行:
方法1:改成非贪婪匹配
在.*后加?,让匹配行为变为非贪婪,遇到第一个\\n就停止。注意Ansible中反斜杠需要转义为\\\\:
- name: Get version set_fact: version: "{{ show_version.stdout | regex_search('Software Version.*?(?=\\\\n)') }}"
方法2:限定匹配的字符范围
直接指定只匹配Software Version后面**不是\和n**的字符,遇到\\n自动停止匹配:
- name: Get version set_fact: version: "{{ show_version.stdout | regex_search('Software Version[^\\\\n]*') }}"
额外技巧:只提取版本号
如果不需要整行内容,只想获取v22.1.1这个版本值,可以用捕获组提取冒号后的内容:
- name: Get version number set_fact: version_num: "{{ show_version.stdout | regex_search('Software Version\\s*:\\s*(.*?)(?=\\\\n)', '\\1') }}"
内容的提问来源于stack exchange,提问作者Dave0
相关产品推荐
相关产品推荐

