この投稿はAnsible 3 Advent Calendar 2019の4日目の記事です。
リスト内にある重複している辞書の数を確認する時のフィルター例です。
ここではシーケンスをリスト、マッピングを辞書と表現します
Playbook
Playbookはこんな感じです。
---
- name: san no kata playbook
hosts: localhost
gather_facts: no
vars:
damon_slayer:
- name: 竈門炭治郎
type: 水
partner: 天王寺松衛門
- name: 嘴平伊之助
type: 獣
partner: ''
- name: 我妻善逸
type: 雷
partner: チュン太郎
- name: 竈門炭治郎
type: 水
partner: 天王寺松衛門
- name: 竈門炭治郎
type: 水
partner: 天王寺松衛門
- name: 嘴平伊之助
type: 獣
partner: ''
tasks:
- name: set list1 variable
set_fact:
list1: >-
{{ list1 | default([])
+ [ damon_slayer
| selectattr("name", "equalto", item.name)
| list
]
}}
loop: "{{ damon_slayer }}"
- debug:
msg: >-
{{ item.0 }} : {{ count }}
vars:
count: "{{ item | length }}"
loop: "{{ list1 | unique }}"
loop_control:
label: "{{ item.0.name }}"
ここでは name
キーがマッチした場合に list1
にまとめて、最後に unique
して loop
で回し数をカウントした結果を表示します。
Playbook実行
これを実行します。
(venv) [root@localhost ansible]# ansible-playbook main.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [san no kata playbook] *****************************************************************************************************************************************************
TASK [set list1 variable] *******************************************************************************************************************************************************
ok: [localhost] => (item={'name': '竈門炭治郎', 'type': '水', 'partner': '天王寺松衛門'})
ok: [localhost] => (item={'name': '嘴平伊之助', 'type': '獣', 'partner': ''})
ok: [localhost] => (item={'name': '我妻善逸', 'type': '雷', 'partner': 'チュン太郎'})
ok: [localhost] => (item={'name': '竈門炭治郎', 'type': '水', 'partner': '天王寺松衛門'})
ok: [localhost] => (item={'name': '竈門炭治郎', 'type': '水', 'partner': '天王寺松衛門'})
ok: [localhost] => (item={'name': '嘴平伊之助', 'type': '獣', 'partner': ''})
TASK [debug] ********************************************************************************************************************************************************************
ok: [localhost] => (item=竈門炭治郎) => {
"msg": "{'name': '竈門炭治郎', 'type': '水', 'partner': '天王寺松衛門'} : 3"
}
ok: [localhost] => (item=嘴平伊之助) => {
"msg": "{'name': '嘴平伊之助', 'type': '獣', 'partner': ''} : 2"
}
ok: [localhost] => (item=我妻善逸) => {
"msg": "{'name': '我妻善逸', 'type': '雷', 'partner': 'チュン太郎'} : 1"
こんな感じでカウントできます。
例えば他のキーのand条件を取りたい場合は以下のように selectattr
を増やします。
---
- name: san no kata playbook
hosts: localhost
gather_facts: no
vars:
damon_slayer:
- name: 竈門炭治郎
type: 水
partner: 天王寺松衛門
- name: 嘴平伊之助
type: 獣
partner: ''
- name: 我妻善逸
type: 雷
partner: チュン太郎
- name: 竈門炭治郎
type: 水
partner: 天王寺松衛門
- name: 竈門炭治郎
type: 水
partner: 天王寺松衛門
- name: 竈門炭治郎
type: 火
partner: 天王寺松衛門
- name: 嘴平伊之助
type: 獣
partner: ''
tasks:
- name: set list1 variable
set_fact:
list1: >-
{{ list1 | default([])
+ [ damon_slayer
| selectattr("name", "equalto", item.name)
| selectattr("type", "equalto", item.type)
| list
]
}}
loop: "{{ damon_slayer }}"
- debug:
msg: >-
{{ item.0 }} : {{ count }}
vars:
count: "{{ item | length }}"
loop: "{{ list1 | unique }}"
loop_control:
label: "{{ item.0.name }}"
実行してみます。
(venv) [root@localhost ansible]# ansible-playbook main.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [san no kata playbook] *****************************************************************************************************************************************************
TASK [set list1 variable] *******************************************************************************************************************************************************
ok: [localhost] => (item={'name': '竈門炭治郎', 'type': '水', 'partner': '天王寺松衛門'})
ok: [localhost] => (item={'name': '嘴平伊之助', 'type': '獣', 'partner': ''})
ok: [localhost] => (item={'name': '我妻善逸', 'type': '雷', 'partner': 'チュン太郎'})
ok: [localhost] => (item={'name': '竈門炭治郎', 'type': '水', 'partner': '天王寺松衛門'})
ok: [localhost] => (item={'name': '竈門炭治郎', 'type': '水', 'partner': '天王寺松衛門'})
ok: [localhost] => (item={'name': '竈門炭治郎', 'type': '火', 'partner': '天王寺松衛門'})
ok: [localhost] => (item={'name': '嘴平伊之助', 'type': '獣', 'partner': ''})
TASK [debug] ********************************************************************************************************************************************************************
ok: [localhost] => (item=竈門炭治郎) => {
"msg": "{'name': '竈門炭治郎', 'type': '水', 'partner': '天王寺松衛門'} : 3"
}
ok: [localhost] => (item=嘴平伊之助) => {
"msg": "{'name': '嘴平伊之助', 'type': '獣', 'partner': ''} : 2"
}
ok: [localhost] => (item=我妻善逸) => {
"msg": "{'name': '我妻善逸', 'type': '雷', 'partner': 'チュン太郎'} : 1"
}
ok: [localhost] => (item=竈門炭治郎) => {
"msg": "{'name': '竈門炭治郎', 'type': '火', 'partner': '天王寺松衛門'} : 1"
}
PLAY RECAP **********************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
重複している辞書の数が確認できました :)