使用 Ansible 时如何操作数组中的每个项目

How to manipuate each item in a array when using Ansible

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

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

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

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

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

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

基于@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"
}

Q: "How to manipulate each item in an array when using Ansible?"

答:可以 map regex_replace 过滤器。例如 play

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

给予

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


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

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

replace: ''

  • 匹配之前定义的捕获组No.2