Given the CSV file for testing
shell> cat /tmp/data_today.csv
idm idc day time
34 3 2023-02-09 12:57:34
34 3 2023-02-09 12:56:34
56 6 2023-02-10 20:25:12
56 5 2023-02-10 20:25:12
78 2 2023-02-11 04:01:00
77 2 2023-02-11 04:01:00
78 2 2023-02-08 04:01:00
Declare the variable
csv_content: "{{ data_today_csv.list }}"
and read the file
- read_csv:
path: /tmp/data_today.csv
delimiter: ' '
register: data_today_csv
gives
csv_content:
- {day: '2023-02-09', idc: '3', idm: '34', time: '12:57:34'}
- {day: '2023-02-09', idc: '3', idm: '34', time: '12:56:34'}
- {day: '2023-02-10', idc: '6', idm: '56', time: '20:25:12'}
- {day: '2023-02-10', idc: '5', idm: '56', time: '20:25:12'}
- {day: '2023-02-11', idc: '2', idm: '78', time: '04:01:00'}
- {day: '2023-02-11', idc: '2', idm: '77', time: '04:01:00'}
- {day: '2023-02-08', idc: '2', idm: '78', time: '04:01:00'}
Declare the list order_by and create the index
order_by: [day, time, idm, idc]
index: |
{% for i in csv_content %}
- index: {{ order_by|map('extract', i)|join('_') }}
{% endfor %}
gives
index: |-
- index: 2023-02-09_12:57:34_34_3
- index: 2023-02-09_12:56:34_34_3
- index: 2023-02-10_20:25:12_56_6
- index: 2023-02-10_20:25:12_56_5
- index: 2023-02-11_04:01:00_78_2
- index: 2023-02-11_04:01:00_77_2
- index: 2023-02-08_04:01:00_78_2
zip and combine the lists
csv_index: "{{ csv_content|zip(index|from_yaml)|map('combine') }}"
gives
csv_index:
- {day: '2023-02-09', idc: '3', idm: '34', index: '2023-02-09_12:57:34_34_3', time: '12:57:34'}
- {day: '2023-02-09', idc: '3', idm: '34', index: '2023-02-09_12:56:34_34_3', time: '12:56:34'}
- {day: '2023-02-10', idc: '6', idm: '56', index: '2023-02-10_20:25:12_56_6', time: '20:25:12'}
- {day: '2023-02-10', idc: '5', idm: '56', index: '2023-02-10_20:25:12_56_5', time: '20:25:12'}
- {day: '2023-02-11', idc: '2', idm: '78', index: '2023-02-11_04:01:00_78_2', time: '04:01:00'}
- {day: '2023-02-11', idc: '2', idm: '77', index: '2023-02-11_04:01:00_77_2', time: '04:01:00'}
- {day: '2023-02-08', idc: '2', idm: '78', index: '2023-02-08_04:01:00_78_2', time: '04:01:00'}
sort by the attribute index
csv_sort: "{{ csv_index|sort(attribute='index') }}"
gives
csv_sort:
- {day: '2023-02-08', idc: '2', idm: '78', index: '2023-02-08_04:01:00_78_2', time: '04:01:00'}
- {day: '2023-02-09', idc: '3', idm: '34', index: '2023-02-09_12:56:34_34_3', time: '12:56:34'}
- {day: '2023-02-09', idc: '3', idm: '34', index: '2023-02-09_12:57:34_34_3', time: '12:57:34'}
- {day: '2023-02-10', idc: '5', idm: '56', index: '2023-02-10_20:25:12_56_5', time: '20:25:12'}
- {day: '2023-02-10', idc: '6', idm: '56', index: '2023-02-10_20:25:12_56_6', time: '20:25:12'}
- {day: '2023-02-11', idc: '2', idm: '77', index: '2023-02-11_04:01:00_77_2', time: '04:01:00'}
- {day: '2023-02-11', idc: '2', idm: '78', index: '2023-02-11_04:01:00_78_2', time: '04:01:00'}
Use Jinja to write the sorted data
- debug:
msg: |
{% for i in csv_sort %}
{{ order_by|map('extract', i)|join(' ') }}
{% endfor %}
gives
msg: |-
2023-02-08 04:01:00 78 2
2023-02-09 12:56:34 34 3
2023-02-09 12:57:34 34 3
2023-02-10 20:25:12 56 5
2023-02-10 20:25:12 56 6
2023-02-11 04:01:00 77 2
2023-02-11 04:01:00 78 2
This template works if all columns are in the list order_by. The last example would work also with a subset of columns in order_by.
Example of a complete playbook for testing
- hosts: localhost
vars:
order_by: [day, time, idm, idc]
csv_content: "{{ data_today_csv.list }}"
index: |
{% for i in csv_content %}
- index: {{ order_by|map('extract', i)|join('_') }}
{% endfor %}
csv_index: "{{ csv_content|zip(index|from_yaml)|map('combine') }}"
csv_sort: "{{ csv_index|sort(attribute='index') }}"
tasks:
- read_csv:
path: /tmp/data_today.csv
delimiter: ' '
register: data_today_csv
- debug:
var: csv_content|to_yaml
- debug:
var: index
- debug:
var: csv_index|to_yaml
- debug:
var: csv_sort|to_yaml
- debug:
msg: |
{% for i in csv_sort %}
{{ order_by|map('extract', i)|join(' ') }}
{% endfor %}
Example of a playbook to write the sorted file
- hosts: localhost
vars:
delimiter: ' '
csv_content: "{{ data_today_csv.list }}"
order_by: [day, time, idm, idc]
index: |
{% for i in csv_content %}
- index: {{ order_by|map('extract', i)|join('_') }}
{% endfor %}
csv_sort: "{{ csv_content|
zip(index|from_yaml)|
map('combine')|
sort(attribute='index') }}"
tasks:
- read_csv:
path: /tmp/data_today.csv
delimiter: "{{ delimiter }}"
register: data_today_csv
- copy:
dest: /tmp/data_today_order.csv
content: |
{{ _keys|join(delimiter) }}
{% for i in csv_sort %}
{{ _keys|map('extract', i)|join(delimiter) }}
{% endfor %}
vars:
_keys: "{{ csv_content.0.keys()|list }}"
gives
shell> cat /tmp/data_today_order.csv
idm idc day time
78 2 2023-02-08 04:01:00
34 3 2023-02-09 12:56:34
34 3 2023-02-09 12:57:34
56 5 2023-02-10 20:25:12
56 6 2023-02-10 20:25:12
77 2 2023-02-11 04:01:00
78 2 2023-02-11 04:01:00