文字列を指定文字で分割して配列にバラすsplit
と、配列を指定文字で結合して文字列に合成するjoin
は、文字列と配列操作において大変有用。
主要なプログラミング言語には大抵この関数/メソッドは用意されており(※俺調べ)、フィルタ系の処理を書くときには重宝する。
Ansibleでこれらを活用するシチュエーションがどれくらいあるかはともかく、Ansibleでもsplit
とjoin
を使うことができるのでその方法についてまとめ。
なお、環境はAnsible 2.10.5 時点。
split
Ansibleとしてはちょっとトリッキーかもしれないが、string型の変数に対してPythonのstr#split()
が使用できる。
※ 時期バージョンではフィルターとしてsplitが使えるようになる模様
- name: split vars: string: 'tokyo, yokohama, fukuoka' debug: msg: "{{ string.split(',') }}"
実行結果
ok: [localhost] => msg: - tokyo - ' yokohama' - ' fukuoka'
このとおり、,
で分割して配列化できている。
が、,
の後ろのスペースを除去できてないので配列要素にスペースが入っており綺麗な状態になっていない。
,
の後ろの必ずスペース1文字しかないという書式であれば正規表現を使うまでもないが、そこが不明瞭であれば、やっぱり m/,\s*/
を使いたいところ。
Pythonのstr#split()
は正規表現を直接指定できずre
と連携する必要があるため、Ansibleから使うのはちょっと厳しい(やりかたがわからなかった)
なので一旦正規表現を使った文字列置換を一度行い、その後にsplit
をすれば大体良い感じにできる。
(これは状況に因るので要件によって適切な方法を検討すること)
- name: split vars: string: 'tokyo, yokohama, fukuoka,sapporo, sendai, tokorozawa' debug: msg: "{{ (string | regex_replace(',\\s*', ',')).split(',') }}"
この例のように、対象文字列string
のデリミタで、,
の後にスペースがあったりなかったり、あっても2つ以上のスペースだったり、、、という場合、regex_replace
を使って「綺麗に」してあげれば、実行結果は以下の通り。
ok: [localhost] => msg: - tokyo - yokohama - fukuoka - sapporo - sendai - tokorozawa
余計なスペースが入っておらず、綺麗になった。
フィルターとしてのsplitについての情報はこちら。
join
Jinja2テンプレートのフィルタとして用意されているjoin()
を使用できる。
- name: join sample vars: sample_items: - foo - bar - baz debug: msg: - "{{ sample_items }}" - "{{ sample_items | join('<>') }}"
「['foo', 'bar', 'baz']
という配列に対して、join
を使って<>
で連結」という内容。
実行すると以下の通り。
ok: [localhost] => msg: - - foo - bar - baz - foo<>bar<>baz
まとめ
split
はファイルパスやURLの文字列を操作するためのsplit系フィルタは用意されてるが、任意の文字列に対する汎用処理を行うフィルタはない。ただし、Pythonのメソッドを使用することが可能。
join
はJinaj2のフィルタを使えばOK
split
とjoin
は(ログファイル解析などで)めっちゃ応用が利くので、インフラの人も正規表現とセットで覚えるべき。