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"