Reputation: 7
Let's consider following output of some command (it is debug of 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"
]
The output is registered in variable output
using command
task. Now, I need to parse it into a list of the form: [some_word1,some_word2,some_word3,some_word4]
.
Please keep in mind that output can contain more or less (even 0) than 4 words.
When it comes to "X","Y","Z"
they are constant (always three lines) so I can skip it using:
- debug:
msg: "{{ output.stdout_lines[3:] }}"
However, I don't know how to deal with leading spaces and digit.
Could you give me some clues, please?
Upvotes: 1
Views: 2104
Reputation: 39119
Knowing a string is "just" a list of char in python, if your output is always
/[[:space:]]+[[:digit:]] (.*)/
and never
/[[:space:]]+[[:digit:]]+ (.*)/
e.g. 1 some_word1
or 9 some_word9
but not 10 some_word10
Then you could apply the trim
filter and just reuse your same list index trick, ending with this jinja expression:
---
- 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:] }}"
This outputs:
/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
Now if you have the second form, or if you want to make it more the bash way, then you could change your command
to a shell
– because shell accepts piping when command does not – and pipe your output to 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:] }}"
This outputs:
/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
Upvotes: 1