使用Ansible时如何处理数组中的每个项目

时间:2019-09-22 05:17:34

标签: ansible ansible-filter

特殊变量ansible_role_names包含一个数组,其中包含角色名称。例如

"ansible_role_names": [
    "geerlingguy.nfs", 
    "ANXS.openssh", 
    "robertdebock.bootstrap", 
    "robertdebock.squid"
]

我要访问的列表是删除点之前所有内容的列表。

"roles": [
    "nfs", 
    "openssh", 
    "bootstrap", 
    "squid"    ]

3 个答案:

答案 0 :(得分:3)

  

Q:“使用Ansible时如何操作数组中的每个项目?”

A:可以 map regex_replace过滤器。例如剧本

- set_fact:
    my_list: "{{ ansible_role_names|
                 map('regex_replace', regex, replace)|
                 list }}"
  vars:
    regex: '^(.*)\.(.*)$'
    replace: '\2'
- debug:
    var: my_list

给予

"my_list": [
    "nfs", 
    "openssh", 
    "bootstrap", 
    "squid"
]


    regex: '^(.*)\.(.*)$'

  • ^匹配字符串的开头
  • (.*)与捕获组1中的任何字符匹配
  • \.匹配.
  • (.*)与捕获组2中的任何字符匹配
  • $匹配字符串的结尾

replace: '\2'

  • \2与先前定义的捕获组2匹配

答案 1 :(得分:2)

您可以使用split过滤器来获取它:

- debug:
    msg: "{{ item.split('.')[-1] }}"
  loop: "{{ ansible_role_names }}"

答案 2 :(得分:2)

建立在@Arbab Nazar答案上:在点上分割字符串并在结果列表上使用索引1有时会中断。

  • 如果您的角色名称不包含点(对于本地角色来说很常见),则会出现错误,其中包含未定义的变量=> list object has no element 1
  • 在(不太可能...)的情况下,您的角色名称中有多个点,您将始终获得字符串中的第二个元素,而不是最后一个

使用-1作为索引(例如,从末尾开始的第一个元素)将解决以下两个潜在问题:

- debug:
    msg: "{{ item.split('.')[-1] }}"
  loop:
    - simplerole
    - classic.galaxyrole
    - non.standard.customrole

哪个给出以下结果:

TASK [debug] ************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=simplerole) => {
    "msg": "simplerole"
}
ok: [localhost] => (item=classic.galaxyrole) => {
    "msg": "galaxyrole"
}
ok: [localhost] => (item=non.standard.customrole) => {
    "msg": "customrole"
}