I tried to sort Linux block device used by ansible_facts
.
I want to sort by alphabetical order and length.
Expected result
sda, sdb ,sdc, ..., sdaa, sdab, ..., sdbb
Current result
sda, sdaa, sdab, sdac ..., sdb, sdb, sdba, sdbb, sdbc, ...
How can I sort sdaa
device after sdz
device?
- name: test
hosts: localhost
vars:
- device: [sda,sdab,sdac,sdb,sdc,sdd,sde,sdf,sdg,sdh,sdi,sdj,sdk,sdl,sdm,sdn,sdo,sdp,sdq,sdr,sds,sdt,sdu,sdv,sdw,sdx,sdy,sdz,sdaa]
tasks:
- name: test
debug:
msg: "{{ device | sort }}"
The result is
ok: [localhost] => {
"msg": [
"sda",
"sdaa",
"sdab",
"sdac",
"sdb",
"sdc",
"sdd",
"sde",
"sdf",
"sdg",
"sdh",
"sdi",
"sdj",
"sdk",
"sdl",
"sdm",
"sdn",
"sdo",
"sdp",
"sdq",
"sdr",
"sds",
"sdt",
"sdu",
"sdv",
"sdw",
"sdx",
"sdy",
"sdz"
]
}
Flatten lists sorted by the length of the items. Create the below list of lists
dmin: "{{ device|map('length')|min }}"
dmax: "{{ device|map('length')|max }}"
device_sorted_lists: |
{% filter from_yaml %}
{% for len in range(dmin|int, dmax|int + 1) %}
{% set regex='^.{' ~ len ~ '}$' %}
- {{ device|select('regex', regex)|sort }}
{% endfor %}
{% endfilter %}
Flatten the lists
device_sorted: "{{ device_sorted_lists|flatten }}"
gives
device_sorted:
- sda
- sdb
- sdc
- sdd
- sde
- sdf
- sdg
- sdh
- sdi
- sdj
- sdk
- sdl
- sdm
- sdn
- sdo
- sdp
- sdq
- sdr
- sds
- sdt
- sdu
- sdv
- sdw
- sdx
- sdy
- sdz
- sdaa
- sdab
- sdac
Example of a complete playbook for testing
- hosts: all
vars:
device: [sda,sdab,sdac,sdb,sdc,sdd,sde,sdf,sdg,sdh,sdi,sdj,sdk,sdl,sdm,sdn,sdo,sdp,sdq,sdr,sds,sdt,sdu,sdv,sdw,sdx,sdy,sdz,sdaa]
dmin: "{{ device|map('length')|min }}"
dmax: "{{ device|map('length')|max }}"
device_sorted_lists: |
{% filter from_yaml %}
{% for len in range(dmin|int, dmax|int + 1) %}
{% set regex='^.{' ~ len ~ '}$' %}
- {{ device|select('regex', regex)|sort }}
{% endfor %}
{% endfilter %}
device_sorted: "{{ device_sorted_lists|flatten }}"
tasks:
- debug:
var: device_sorted_lists
- debug:
var: device_sorted