4
0

More than 3 years have passed since last update.

Ansibleの呼吸 参ノ型 フィルター芸「リスト内にある重複している辞書の数を確認」

Last updated at Posted at 2019-12-12

この投稿は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

重複している辞書の数が確認できました :)

4
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0