Ansible从列表变量的匹配元素中提取子字符串

Ansible从列表变量的匹配元素中提取子字符串,ansible,jinja2,ansible-filter,Ansible,Jinja2,Ansible Filter,我有一个变量,它是一个列表,如下所示: "test_list": [ "some text here", "server1", "command1 parameter1", "path/to/command2 parameter2 server1_202012", "some more text", "New backup file is server1_202019" ] "test_name": "server1_2020

我有一个变量,它是一个列表,如下所示:

"test_list": [
     "some text here",
     "server1",
     "command1 parameter1",
     "path/to/command2 parameter2 server1_202012",
     "some more text",
     "New backup file is server1_202019"
    ]
"test_name": "server1_202019"
我正在尝试提取子字符串
server1\u 202019
,它位于以
新备份文件开始的行的末尾…
。只有一行是这样的,我在下面的选项中尝试获取子字符串

- set_fact: 
    test_name: "{{ test_list | select('^New backup file is (.+)$','\\1') }}" 
我收到的结果是:

"test_name": "<generator object _select_or_reject at 0x3fe5b40>" 
错误是:

"msg": "Unexpected templating type error occurred on ({{ test_list | regex_search('^New backup file is (.+)$','\\\\1') }}): ..... expected string or buffer"
有人可以建议我如何获得以下输出:

"test_list": [
     "some text here",
     "server1",
     "command1 parameter1",
     "path/to/command2 parameter2 server1_202012",
     "some more text",
     "New backup file is server1_202019"
    ]
"test_name": "server1_202019"
我使用的ansible版本是2.9


谢谢

因为
测试列表
是一个列表,所以您需要使用regex遍历要匹配的项目。可以做下面这样的事情

- 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'}) 

从列表中选择项目,然后使用
regex\u 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: '\1'
    - debug:
        var: test_name
给予


这只适用于最后一行。否则,结果为空字符串。谢谢。我已经更新了代码,并且从你的帖子中学习到了很多东西。谢谢你,Mamun,我在编辑之前尝试了代码,结果输出是空的。欢迎你。是的,更新了@VladimirBotka指出的代码。从你的问题中学到了一些新的东西。非常感谢博卡,它工作得非常好。我还了解到,“第一个”用于解决“generator object\u select\u或\u reject at 0x3fe5b40”问题。对,这取决于您想要什么。如果需要,使用过滤器
list
获取完整列表。不客气。