備忘
dictionary や list_of_dictionaries 構造などにおいて使用できるフィルターなど
- hosts: all
gather_facts: false
tasks:
# list -> 全要素の数
# |length
- debug: { msg: "{{ [ 0, 1, 2, ]|length }}" } # "3"
# list -> 特定の要素の数
# .count()
- debug: { msg: "{{ ['a', 'b', 'c', 'b'] .count('b') }}" } # "2" listにおける要素の数
# list -> 要素の場所(最初)
# .index()
- debug: { msg: "{{ ['a', 'b', 'c', 'b'] .index('b') }}" } # "1" listにおけるその値の要素の最初の場所。0始まり。
# list -> 特定の場所の要素
# []
# |first
# |last
- debug: { msg: "{{ ['a', 'b', 'c', 'd'][1] }}" } # "b" listにおけるその場所(0始まり)の値
- debug: { msg: "{{ ['a', 'b', 'c', 'd'][-2] }}" } # "c" マイナスの場合は末尾から(-1始まり)
- debug: { msg: "{{ ['a', 'b', 'c', 'd']|first }}" } # "a" [0]と同じ
- debug: { msg: "{{ ['a', 'b', 'c', 'd']|last }}" } # "d" [-1]と同じ
# list -> 逆順のlist
# |reverse
- debug: { msg: "{{ ['a', 'b']|reverse }}" } # ['b', 'a'] listにおける要素を逆順に
# list -> 値が指定条件を満たすlistを抽出
# |select()
- debug: { msg: "{{ ['a', 'b', 'c'] | select('==','b') }}" } # ["b"]
- debug: { msg: "{{ ['a', 'b', 'b'] | select('==','b') }}" } # ["b", "b"]
- debug: { msg: "{{ ['a', 'b', 'c'] | select('==','d') }}" } # []
- debug: { msg: "{{ ['c', 'b', 'a'] | select('<=','b') }}" } # ["b", "a"]
- debug: { msg: "{{ ['c', 'b', 'a'] | select('>=','b') }}" } # ["c", "b"]
- debug: { msg: "{{ ['c', 'b', 'a'] | select('<','b') }}" } # ["a"]
- debug: { msg: "{{ ['c', 'b', 'a'] | select('>','b') }}" } # ["c"]
- debug: { msg: "{{ ['a', '(b)', 'c'] | select('match', '\\(.*\\)') | list }}" } # ["(b)"]
# https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-filters.select
# 使えるテストは以下という理解だが、matchが見当たらない^^;
# https://jinja.palletsprojects.com/en/3.0.x/templates/#list-of-builtin-tests
# Ansibleにより提供されたフィルターか
# https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_tests.html#testing-strings
# list -> 各要素にfilterを適用したlistを作成
# |map()
- debug: { msg: "{{ ['a', 'b', 'c'] | map('upper') }}" } # [ "A", "B", "C" ] # filterへの引数はmap内で","区切りで指定
# https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-filters.map
# listと値 -> (listの要素をkeyとする)dictを作成
# .fromkeys()
- debug: { msg: "{{ {}.fromkeys(['a','b'],0) }}" } # { "a": 0, "b": 0 } listの要素をキーとするdictを作成
- debug: { msg: "{{ {}.fromkeys(['a','b'],[7,8]) }}" } # { "a": [ 7, 8 ], "b": [ 7, 8 ] } listの要素をキーとするdictを作成
# list -> dict
# items2dict
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#transforming-lists-into-dictionaries
# dict -> 特定のkeyのvalueを抽出
# []
# .KEY
# .get()
- debug: { msg: "{{ {'k0': 'v0', 'k1': 'v1'}['k1'] }}" } # "v1"
- debug: { msg: "{{ {'k0': 'v0', 'k1': 'v1'}.k1 }}" } # "v1" 注: 指定キーが予約語(例えばindexなど)と重複する場合、この書式は使用できない
- debug: { msg: "{{ {'k0': 'v0', 'k1': 'v1'}.get('k1') }}" } # "v1"
# list_of_dict -> 特定のkeyに対応するvalueを抜き出してlistを作成
# |map(attribute=KEY)
- debug: { msg: "{{ [{'k1': 'v11', 'k2': 'v12'}, {'k1': 'v21', 'k2': 'v22'}]|map(attribute='k2')|list }}" } # [ "v12", "v22" ] なお、"|list"は新しいansibleでは不要かも
# list_of_dict -> 指定したkeyに関してグルーピングしたlistを作成
# |groupby()
- debug:
msg: "{{ address_book|groupby('addr') }}"
vars:
address_book:
- {name: foo, addr: tok}
- {name: bar, addr: tok}
- {name: baz, addr: chiba}
register: r
# 結果
# - - chiba
# - - {name: baz, addr: chiba}
# - - tok
# - - {name: foo, addr: tok}
# - {name: bar, addr: tok}
# list_of_dict -> 特定の要件を満たす部分集合
# |selectattr(key,test,arg)
# |rejectattr(key,test,arg)
# testには、==などの他にinやcontainsといったものも使用可能
# https://zaki-hmkc.hatenablog.com/entry/2021/02/18/000228
# dict -> keysのlistを作成
# .keys()
- debug: { msg: "{{ {'k0': 'v0', 'k1': 'v1'}.keys() }}" } # ["k0", "k1"]
# dict -> valesのlistを作成
# .values()
- debug: { msg: "{{ {'k0': 'v0', 'k1': 'v1'}.values() }}" } # ["v0", "v1"]
# dict -> [キー, 値]のlistに変換
# .items()
- debug: { msg: "{{ {'k0': 'v0', 'k1': 'v1'}.items() }}" } # [["k0", "v0"], ["k1", "v1"]]
- debug: { msg: "{{ {'k1': 'v1', 'k0': 'v0'}.items() }}" } # [["k1", "v1"], ["k0", "v0"]] # 順序が考慮されていて上の行と同じ結果でない。バージョンなどにより結果が異る可能性。
# dict -> key:,value:書式dictのlistを作成 (loop:の引数などに利用可能)
# |dict2items
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#transforming-dictionaries-into-lists
# k0: v0
# k1: v1
# ↓
# - key: k0
# value: v0
# - key: k1
# value: v1
- debug: { msg: "{{ {'k0': 'v0', 'k1': 'v1'}|dict2items|list }}" } # [{"key": "k0", "value": "v0"}, {"key": "k1", "value": "v1"}] なお、"|list"は新しいansibleでは不要かも
# key,valueのlistのlistをdictに変換
# dict(...)
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-items-from-multiple-lists-zip-and-zip-longest
# - - k0
# - v0
# - - k1
# - v1
# ↓
# k0: v0
# k1: v1
- debug: { var: dict( [['k1','v1'], ['k2','v2']] ) } # => { "k1": "v1", "k2": "v2" }
# ある要素がキー->下位listとなっているlist -> そのキー以下のlistを用いた疑似2重ループ用のデータに変換
# |subelements(キー)
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-objects-and-subelements
- debug:
msg: "{{ users|subelements('groups') }}"
vars:
users:
- name: user1
groups: [wheel, hoge]
- name: user2
groups: [hoge]
# 結果
# - - name: user1
# groups: [wheel, hoge]
# - wheel
# - - name: user1
# groups: [wheel, hoge]
# - hoge
# - - name: user2
# groups: [hoge]
# - hoge
# dict -> changedキーやfailedキーなどに対する値(true/false)
# is changed
# ['changed']
# .changed
- debug: { msg: "{{ {'changed': true } is changed }}" } # true
- debug: { msg: "{{ {'changed': false} is changed }}" } # false
- debug: { msg: "{{ { } is changed }}" } # false 'changed'キーがなくともエラーにならない
- debug: { msg: "{{ { } is not changed }}" } # true 'changed'キーがなくともエラーにならない
- debug: { msg: "{{ {'changed': true }['changed'] }}" } # true
- debug: { msg: "{{ {'changed': true }.changed }}" } # true
# - debug: { msg: "{{ { }.changed }}" } # 'dict object' has no attribute 'changed'
# 要素1が集合2に含まれるかどうか、文字列string1がstring2 に含まれるかどうか
# 要素 in 集合
# string1 in string2
# string1.find(string2)
- debug: { msg: "{{ 'a' in ['a', 'b', 'c'] }}" } # true
- debug: { msg: "{{ 'z' in ['a', 'b', 'c'] }}" } # false
# - debug: { msg: "{{ ['a', 'b', 'c'].find('a') }}" } # 'list object' has no attribute 'find'
- debug: { msg: "{{ 'ab' in 'abcd' }}" } # true
- debug: { msg: "{{ 'ba' in 'abcd' }}" } # false
- debug: { msg: "{{ 'ab' not in 'abcd' }}" } # false
- debug: { msg: "{{ 'abcd'.find('ab') }}" } # 0
- debug: { msg: "{{ 'abcd'.find('ba') }}" } # -1
# https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-tests.in
# 型の表示
- debug: { msg: "{{ 1|type_debug }}" } # "int"
- debug: { msg: "{{ []|type_debug }}" } # "list"
- debug: { msg: "{{ {}|type_debug }}" } # "dict"
- debug: { msg: "{{ true|type_debug }}" } # "bool"
- debug: { msg: "{{ 'abc'|type_debug }}" } # "str"
- debug: { msg: "{{ 'あいうえお'|type_debug }}" } # "str"
- debug: { msg: "{{ foo|type_debug }}" } # "int"
vars: { foo: 1 }
- debug: { msg: "{{ foo|type_debug }}" } # "int"
vars: { foo: "{{ bar }}", bar: 2 }
- debug: { msg: "{{ foo|type_debug }}" } # "AnsibleUnicode"
vars: { foo: abc }
# 構造化データ -> string
# |to_nice_yaml # ブロックスタイルYAML書式の文字列に変換
# |to_yaml # 下層にフロースタイルを混ぜてより短く表示。個人的にはto_nice_yamlより改行が少く見通しがかなり良い。
# string -> 構造化データ
# |from_yaml # YAML形式の文字列を解釈
# |from_json # JSON形式の文字列を解釈
# 一般的と思われるもの
# == もしくは eq
# != もしくは ne
# > もしくは gt
# < もしくは lt
# >= もしくは ge
# <= もしくは le
# https://jinja.palletsprojects.com/en/3.0.x/templates/#list-of-builtin-filters
# |basename
# |dirname
# |int
# |float
# |bool
# |string
# |sort()
# |join()
# |lower
# |upper
# |b64decode
# |max
# |min
# |sum
# 以下未完
# dict -> キーで並び換え 本来dictsは順序を持たず、実際Pythonでは順序は保証されないが、for loopなどで順序を使用したい場合に使用。
# |dictsort
# 複数の構造化データ -> 単一の構造化データ
# h1|combine(h2,h3,..)
# [h1,h2,h3,...]|combine
# 複数の構造化データ -> 単一の構造化データ Deepマージ
# h1|combine(h2,h3,.. ,recursive=true)
# [h1,h2,h3,...]|combine(recursive=true)
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-hashes-dictionaries
# 構造化データをより高度に扱う
# |json_query()
# 変数が未定義の場合のデフォルト値
# |default(値)
# |default(omit) # 特殊: 未定義の場合にその設定そのものを取り止め
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#providing-default-values
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#making-variables-optional
# string -> 正規表現による置き換え
# |regex_replace('^.* = +(.*)$','\\1')
# |regex_replace('.yml')
# 多重階層のデータをフラット化
# |flatten(levels=0)
# プラグイン
# https://docs.ansible.com/ansible/2.9_ja/plugins/lookup/pipe.html
# lookup('env', 'PWD')
# lookup('pipe', 'date')
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html
# 3項演算
# | ternary(x,y[,z]) # zは値がnullの場合
# x if 式 else y
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#defining-different-values-for-true-false-null-ternary
# set もしくは list
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#selecting-from-sets-or-lists-set-theory
# listから重複削除
# uniq
# 和集合
# union
# 積集合
# intersect
# 差集合
# | difference
# 排他的論理和
# | symmetric_difference
# 複数のlistから要素を1:1で抜き出したもののlistを作成
# | zip()|list
# | zip_longest()|list
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-items-from-multiple-lists-zip-and-zip-longest
# 2要素listのlistからdictを作成
# dict()
- debug: { var: dict([['k1','v1'],['k2','v2']]) } # => {"k1": "v1", "k2": "v2"}
参考