如何在Ansible的regex_replace中传递lambda函数实现版本号递增?
Ah, I get it—you're trying to replicate that handy Python re.sub lambda trick in Ansible, but the regex_replace filter doesn't support passing lambda functions as the replacement value directly. Let's walk through two solid solutions to get your version numbers incremented by 3.
方法一:自定义Ansible过滤器(推荐,可复用)
This is the cleanest approach, especially if you need to use this version-increment logic multiple times. Ansible lets you create custom filters with Python, which can replicate the lambda behavior you're used to.
- First, create a
filter_pluginsdirectory in your playbook's root (Ansible automatically loads filters from here):
mkdir filter_plugins
- Create a filter file (e.g.,
filter_plugins/version_filters.py) with this code:
import re def increment_version_match(match_obj): # Take the captured number, add 3, and format back into "version=X" return f"version={int(match_obj.group(1)) + 3}" def version_add_3(input_string): # Use re.sub with our custom match handler return re.sub(r'version=(\d+)', increment_version_match, input_string) class FilterModule(object): # Tell Ansible about our custom filter def filters(self): return { 'version_add_3': version_add_3 }
- Now use the filter in your playbook:
- name: Increment version numbers by 3 hosts: localhost vars: original_string: "version=3 blah blah blah whatever version=4" tasks: - debug: msg: "{{ original_string | version_add_3 }}"
When you run this, the debug output will be:
msg: version=6 blah blah blah whatever version=7
方法二:纯Jinja2循环替换(临时场景)
If you don't want to create a custom filter for a one-off use, you can use Jinja2's built-in filters to find all matches and replace them one by one:
- name: Increment versions without custom filter hosts: localhost vars: original_string: "version=3 blah blah blah whatever version=4" version_regex: 'version=(\d+)' tasks: - set_fact: updated_string: "{{ updated_string | default(original_string) | regex_replace(full_match, 'version=' ~ (number | int + 3)) }}" loop: "{{ original_string | regex_findall(version_regex, '\\1') | zip(original_string | regex_findall(version_regex)) | list }}" vars: number: "{{ item.0 }}" full_match: "{{ item.1 }}" - debug: msg: "{{ updated_string }}"
How this works:
regex_findall(version_regex, '\\1')extracts all the numeric parts of the version strings (e.g.,['3', '4'])regex_findall(version_regex)extracts the full matched strings (e.g.,['version=3', 'version=4'])zippairs these together, then we loop through each pair, replacing the full match with the incremented version number.
内容的提问来源于stack exchange,提问作者dealeo

