Ansible 从 List 变量的匹配元素中提取子字符串
Ansible extract sub-string from a matched element of a List variable
我有一个变量,它是一个 list,如下所示:
"test_list": [
"some text here",
"server1",
"command1 parameter1",
"path/to/command2 parameter2 server1_202012",
"some more text",
"New backup file is server1_202019"
]
我正在尝试提取以 New backup file...
开头的行末尾的子字符串 server1_202019
。只有一行是这样的,我试过下面的选项来获取子字符串。
- set_fact:
test_name: "{{ test_list | select('^New backup file is (.+)$','\1') }}"
我收到的输出是:
"test_name": "<generator object _select_or_reject at 0x3fe5b40>"
我也试过下面的代码,但失败了。
- set_fact:
test_name: "{{ test_list | regex_search('^New backup file is (.+)$','\1') }}"
错误是:
"msg": "Unexpected templating type error occurred on ({{ test_list | regex_search('^New backup file is (.+)$','\\1') }}): ..... expected string or buffer"
有人可以建议我如何获得如下输出:
"test_name": "server1_202019"
我用的ansible版本是2.9
谢谢
由于test_list
是一个列表,您需要使用正则表达式遍历要匹配的项目。像下面这样的事情是可以做到的。
- set_fact:
matched: "{{ item | regex_search('^New backup file is (.+)$','\1') }}"
loop: "{{ test_list }}"
register: matching_items
- debug:
var: item.ansible_facts.matched
with_items: "{{ matching_items.results }}"
when: item.ansible_facts.matched != ""
调试时应该像下面这样输出:
TASK [debug] *******************************************************************************************************************************
skipping: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ''}, 'failed': False, 'item': 'some text here', 'ansible_loop_var': 'item'})
skipping: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ''}, 'failed': False, 'item': 'server1', 'ansible_loop_var': 'item'})
skipping: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ''}, 'failed': False, 'item': 'command1 parameter1', 'ansible_loop_var': 'item'})
skipping: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ''}, 'failed': False, 'item': 'path/to/command2 parameter2 server1_202012', 'ansible_loop_var': 'item'})
ok: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ['server1_202019']}, 'failed': False, 'item': 'New backup file is server1_202019', 'ansible_loop_var': 'item'}) => {
"ansible_loop_var": "item",
"item": {
"ansible_facts": {
"matched": [
"server1_202019"
]
},
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"item": "New backup file is server1_202019"
},
"item.ansible_facts.matched": [
"server1_202019"
]
}
skipping: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ''}, 'failed': False, 'item': 'some more text', 'ansible_loop_var': 'item'})
Select 列表中的项目,然后使用 regex_replace
。例如
- set_fact:
test_name: "{{ test_list|
select('regex', my_regex)|
first|
regex_replace(my_regex, my_replace) }}"
vars:
my_regex: '^New backup file is (.*)$'
my_replace: ''
- debug:
var: test_name
给予
"test_name": "server1_202019"
我有一个变量,它是一个 list,如下所示:
"test_list": [
"some text here",
"server1",
"command1 parameter1",
"path/to/command2 parameter2 server1_202012",
"some more text",
"New backup file is server1_202019"
]
我正在尝试提取以 New backup file...
开头的行末尾的子字符串 server1_202019
。只有一行是这样的,我试过下面的选项来获取子字符串。
- set_fact:
test_name: "{{ test_list | select('^New backup file is (.+)$','\1') }}"
我收到的输出是:
"test_name": "<generator object _select_or_reject at 0x3fe5b40>"
我也试过下面的代码,但失败了。
- set_fact:
test_name: "{{ test_list | regex_search('^New backup file is (.+)$','\1') }}"
错误是:
"msg": "Unexpected templating type error occurred on ({{ test_list | regex_search('^New backup file is (.+)$','\\1') }}): ..... expected string or buffer"
有人可以建议我如何获得如下输出:
"test_name": "server1_202019"
我用的ansible版本是2.9
谢谢
由于test_list
是一个列表,您需要使用正则表达式遍历要匹配的项目。像下面这样的事情是可以做到的。
- set_fact:
matched: "{{ item | regex_search('^New backup file is (.+)$','\1') }}"
loop: "{{ test_list }}"
register: matching_items
- debug:
var: item.ansible_facts.matched
with_items: "{{ matching_items.results }}"
when: item.ansible_facts.matched != ""
调试时应该像下面这样输出:
TASK [debug] *******************************************************************************************************************************
skipping: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ''}, 'failed': False, 'item': 'some text here', 'ansible_loop_var': 'item'})
skipping: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ''}, 'failed': False, 'item': 'server1', 'ansible_loop_var': 'item'})
skipping: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ''}, 'failed': False, 'item': 'command1 parameter1', 'ansible_loop_var': 'item'})
skipping: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ''}, 'failed': False, 'item': 'path/to/command2 parameter2 server1_202012', 'ansible_loop_var': 'item'})
ok: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ['server1_202019']}, 'failed': False, 'item': 'New backup file is server1_202019', 'ansible_loop_var': 'item'}) => {
"ansible_loop_var": "item",
"item": {
"ansible_facts": {
"matched": [
"server1_202019"
]
},
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"item": "New backup file is server1_202019"
},
"item.ansible_facts.matched": [
"server1_202019"
]
}
skipping: [localhost] => (item={'changed': False, 'ansible_facts': {'matched': ''}, 'failed': False, 'item': 'some more text', 'ansible_loop_var': 'item'})
Select 列表中的项目,然后使用 regex_replace
。例如
- set_fact:
test_name: "{{ test_list|
select('regex', my_regex)|
first|
regex_replace(my_regex, my_replace) }}"
vars:
my_regex: '^New backup file is (.*)$'
my_replace: ''
- debug:
var: test_name
给予
"test_name": "server1_202019"