如何有条件地用regex_replace替换列表中的文本?

时间:2019-05-16 12:05:33

标签: ansible yaml jinja2 ansible-inventory

我的剧本中有一个变量是从列表派生的。在某些情况下,此变量包含用于分隔两个值的“-”。例如,

Numbers:
  - 2211
  - 2211-2212

在这种情况下,我想根据条件将“-”替换为“ _”:如果数字长度为4个字符,请执行此操作。否则,将“-”替换为“ _”,然后执行此操作。

我已经尝试在我的剧本中摆弄jinja2 ans regex,但到目前为止还没有运气。这是我尝试过的,

number: {% if length(item) == 4 %} {{ item | regex_replace("^(.*)$", "Number_\1") | string }} {% else %} {{ item | regex_replace("^(.*)$", "Number_\1") |replace("-", "_") | string }}

我想要的结果,

Number is four characters long:
    number: Number_2211
Number is more then 4 characters long:
    number: Number_2211_2212 

我收到的一些错误消息是

ERROR! Syntax Error while loading YAML.
  did not find expected key

ERROR! Syntax Error while loading YAML.
  found character that cannot start any token

在Ansible剧本中是否有办法实现这一目标? 预先感谢!

2 个答案:

答案 0 :(得分:0)

目前还不清楚您打算如何使用这些数据。 Ansible并不擅长对现有的修改复杂数据结构进行修改,但是它具有许多在访问数据时转换数据的方法。例如,这本剧本:

---
- hosts: localhost
  gather_facts: false
  vars:
    numbers:
      - "2211"
      - "2211-2212"
  tasks:
    - debug:
        msg: "number: {{ item.replace('-', '_') }}"
      loop: "{{ numbers }}"

将输出:

TASK [debug] **********************************************************************************
ok: [localhost] => (item=2211) => {
    "msg": "number: 2211"
}
ok: [localhost] => (item=2211-2212) => {
    "msg": "number: 2211_2212"
}

如果您确实需要根据长度来确定转换的条件(并且不清楚是否这样做),则可以执行以下操作:

- debug:
    msg: "{{ item.replace('-', '_') if item|length > 4 else item }}"
  loop: "{{ numbers }}"

更新

我看到您选择了另一个答案。这里介绍的解决方案似乎简单得多(没有“过滤器,正则表达式和相等性检查的令人费解的序列”),并且产生几乎相同的输出:

TASK [debug] **********************************************************************************
ok: [localhost] => (item=445533) => {
    "msg": "445533"
}
ok: [localhost] => (item=112234-538) => {
    "msg": "112234_538"
}
ok: [localhost] => (item=11) => {
    "msg": "11"
}
ok: [localhost] => (item=1111) => {
    "msg": "1111"
}
ok: [localhost] => (item=1111-1111) => {
    "msg": "1111_1111"
}
ok: [localhost] => (item=11-11) => {
    "msg": "11_11"
}

在给定11-11的情况下,尚不清楚您期望输出11_11还是11-11。如果您希望使用前者,则此答案更为正确。

答案 1 :(得分:0)

您可以使用一系列难以理解的过滤器,正则表达式和相等性检查来做到这一点。

#!/usr/bin/env ansible-playbook
- name: Lets munge some data
  hosts: localhost
  gather_facts: false
  become: false
  vars:
    array:
    - 445533
    - 112234-538
    - 11
    - 1111
    - 1111-1111
    - 11-11
  tasks:
  - name: Replace hypens when starting with 4 numbers
    debug:
      msg: "{{ ((item | string)[0:4] | regex_search('[0-9]{4}') | string != 'None') 
             | ternary((item | regex_replace('-', '_')), item) }}"
    loop: "{{ array }}"

PLAY [Lets munge some data] *****************************************************************************************************************************************************************************************************

TASK [Replace hypens when starting with 4 numbers] ******************************************************************************************************************************************************************************
ok: [localhost] => (item=445533) => {
    "msg": "445533"
}
ok: [localhost] => (item=112234-538) => {
    "msg": "112234_538"
}
ok: [localhost] => (item=11) => {
    "msg": "11"
}
ok: [localhost] => (item=1111) => {
    "msg": "1111"
}
ok: [localhost] => (item=1111-1111) => {
    "msg": "1111_1111"
}
ok: [localhost] => (item=11-11) => {
    "msg": "11-11"
}

PLAY RECAP **********************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0