はじめに
<バージョン>
ansible 2.9.1
以下のような連続スペースで区切られた文字列があり、この中から2番目と3番目が等しい行
だけを抽出したいという場合があると思います。
連続スペースで区切られていることにより、抽出に苦労しました。
サンプル
line1 5 4
line2 5 5 # 2番目と3番目が等しいことを知りたい
line3 5 6
参考Playbook(失敗例)
まずは、連続スペースであることを気にせずにsplitを使ってみます。
(splitはデフォルトでスペースを分割します)
replace_test1.yml
---
- name: replace TEST
hosts: localhost
gather_facts: no
vars:
ansible_python_interpreter: /usr/bin/python3
sample_outputs:
- "line1 5 4 "
- "line2 5 5 "
- "line3 5 6 "
tasks:
- name: 'replace - 1'
debug:
msg: "{{ line_list }}"
vars:
line_list: "{{ item.split(' ') | list }}"
with_items: "{{ sample_outputs }}"
実行結果(失敗例)
replaceの時に連続スペースで毎回分割してしまうので、想定以上のリストの数になってしまいます。
出力1
[ec2-user@ip-<ip-addr> ansible]$ ansible-playbook replace_test1.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [replace TEST] *************************************************************************************************************************************************************************
TASK [replace - 1] **************************************************************************************************************************************************************************
ok: [localhost] => (item=line1 5 4 ) => {
"msg": [
"line1",
"",
"",
"",
"5",
"",
"",
"",
"4",
"",
"",
"",
""
]
}
~一部、省略~
PLAY RECAP **********************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
参考Playbook(成功例)
ポイント
(1)regex_replaceで連続スペースをスペース1つに置換する
(2)(1)の結果をsplitで分割する(splitのデフォルトはスペース)
(3)(2)の結果を取り出す(リストは0から数えるので、1番目と2番目を比較する)
replace_test2.yml
---
- name: replace TEST
hosts: localhost
gather_facts: no
vars:
ansible_python_interpreter: /usr/bin/python3
sample_outputs:
- "line1 5 4 "
- "line2 5 5 "
- "line3 5 6 "
tasks:
- name: 'replace - 2'
debug:
msg: "line_vars[1] : {{ line_vars[1] }} / line_vars[2] : {{ line_vars[2] }}"
when:
- ( line_vars[1] == line_vars[2] ) # ポイント(3)
vars:
output_replace: "{{ item | regex_replace(' +',' ') }}" # ポイント(1)
line_vars: "{{ output_replace.split() }}" # ポイント(2)
with_items: "{{ sample_outputs }}"
実行結果(成功例)
値が等しい時だけ実行されたことがわかります。
出力2
[ec2-user@ip-<ip-addr> ansible]$ ansible-playbook replace_test2.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [replace TEST] *************************************************************************************************************************************************************************
TASK [replace - 2] **************************************************************************************************************************************************************************
skipping: [localhost] => (item=line1 5 4 )
ok: [localhost] => (item=line2 5 5 ) => {
"msg": "line_vars[1] : 5 / line_vars[2] : 5" # 値が等しい時だけ実行された
}
skipping: [localhost] => (item=line3 5 6 )
PLAY RECAP **********************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0