使用jinja2模板在ansible中解析输出(将字符串列表映射到字符串列表)

时间:2019-05-07 18:50:03

标签: ansible jinja2

让我们考虑以下命令的输出(它是stdout_lines的调试):

- command: "some command"
  register: output
- debug: 
    msg: "{{ output.stdout_lines }}"


"msg": [
    "X", 
    "Y", 
    "Z", 
    "   1 some_word1", 
    "   1 some_word2", 
    "   1 some_word3", 
    "   1 some_word4"
]

使用output任务将输出注册到变量command中。现在,我需要将其解析为以下形式的列表:[some_word1,some_word2,some_word3,some_word4]
请记住,输出中可以包含(少于0个)少于4个单词。

当涉及"X","Y","Z"时,它们是恒定的(总是三行),所以我可以使用:

- debug:
    msg: "{{ output.stdout_lines[3:] }}"

但是,我不知道如何处理前导空格和数字。
请给我一些线索吗?

1 个答案:

答案 0 :(得分:0)

如果您的输出始终为

,则知道字符串只是python中的char数组。
/[[:space:]]+[[:digit:]] (.*)/

从不

/[[:space:]]+[[:digit:]]+ (.*)/

例如1 some_word19 some_word9而非10 some_word10

然后,您可以应用trim过滤器并重复使用相同的数组索引技巧,以此jinja表达式结尾:

---
- hosts: local
  vars:
    "msg": [
        "X",
        "Y",
        "Z",
        "   1 some_word1",
        "   1 some_word2",
        "   1 some_word3",
        "   1 some_word4"
    ]

  tasks:
    - debug:
        msg: "{{ (item | trim())[2:] }}" # after trimming the item, we just ignore the first two char as you did for your three first output lines
      with_items: "{{ msg[3:] }}"

这将输出:

/data/playbooks # ansible-playbook so.yml

PLAY [local] *******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [host1]

TASK [debug] *******************************************************************
ok: [host1] => (item=   1 some_word1) => {
    "msg": "some_word1"
}
ok: [host1] => (item=   1 some_word2) => {
    "msg": "some_word2"
}
ok: [host1] => (item=   1 some_word3) => {
    "msg": "some_word3"
}
ok: [host1] => (item=   1 some_word4) => {
    "msg": "some_word4"
}

PLAY RECAP *********************************************************************
host1                      : ok=2    changed=0    unreachable=0    failed=0  

现在,如果您具有第二种形式,或者您想使其更像bash方式,那么您可以将command更改为shellbecause shell accepts piping when command does not –并用管道传输输出到awk

---
- hosts: local

  tasks:
    - shell: printf "X\nY\nZ\n   1 some_word1\n   1 some_word2\n   1 some_word3\n   1 some_word4" |  awk '{print $2}'
      register: output
    - debug:
        msg: "{{ output.stdout_lines[3:] }}"

这将输出:

/data/playbooks # ansible-playbook so.yml

PLAY [local] *******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [host1]

TASK [shell] *******************************************************************
changed: [host1]

TASK [debug] *******************************************************************
ok: [host1] => {
    "msg": [
        "some_word1",
        "some_word2",
        "some_word3",
        "some_word4"
    ]
}

PLAY RECAP *********************************************************************
host1                      : ok=3    changed=1    unreachable=0    failed=0