如何在Ansible中将字典列表的Epoch时间戳转为HH:MM:SS并赋值?
解决Ansible中字典列表的时间戳转换并更新原字段问题
问题背景
我有一个字典列表data,每个字典里的timestamps字段是毫秒级的Epoch时间戳,需要把这些时间戳转换成HH:MM:SS格式。目前写了main.yml和convert-time.yml实现转换,但没法把转换后的列表赋值回原字典的timestamps字段,直接操作item['timestamps']会报语法错误。
数据结构示例:
data = [ { "data": [123, 456], "timestamps": [1620000000000, 1620003600000], "stat": "example" } ]
现有代码:main.yml
- name: reformat times include_tasks: convert-time.yml loop: "{{ data }}"
convert-time.yml
--- - name: set empty list set_fact: timestamps: [] - name: convert epoch time set_fact: timestamps: "{{ timestamps + ['%H:%M:%S' | strftime(item/1000)] }}" loop: "{{ item['timestamps'] }}"
核心问题
Ansible里loop迭代的item是只读的,不能直接修改后赋值回原列表。得重新构建整个data列表,把每个字典的timestamps替换成转换后的结果。
解决方案
方案一:直接在主任务处理(无需拆分文件)
用过滤器组合一步到位,代码更简洁:
- name: 转换并更新data的timestamps字段 set_fact: data: "{{ data | map('combine', {'timestamps': item.timestamps | map('int') | map('div', 1000) | map('strftime', '%H:%M:%S') | list}) | list }}" loop: "{{ data }}"
方案二:保留拆分任务的方式
如果一定要分文件处理,得把转换后的结果传递回主任务,再构建新列表:
修改后的main.yml:
- name: 初始化空的更新列表 set_fact: updated_data: [] - name: 处理每个字典的时间戳 include_tasks: convert-time.yml loop: "{{ data }}" loop_control: loop_var: original_item # 重命名循环变量,避免子任务冲突 - name: 查看最终结果 debug: var: updated_data
修改后的convert-time.yml:
--- - name: 批量转换时间戳为HH:MM:SS set_fact: converted_timestamps: "{{ original_item.timestamps | map('int') | map('div', 1000) | map('strftime', '%H:%M:%S') | list }}" - name: 把更新后的字典加入新列表 set_fact: updated_data: "{{ updated_data + [original_item | combine({'timestamps': converted_timestamps})] }}"
关键说明
- 原时间戳是毫秒级,必须用
div(1000)转成秒级,strftime才能正常处理。 combine过滤器用来合并原字典和新的timestamps字段,生成更新后的字典。- 用
loop_control重命名循环变量,避免子任务里的item和主任务冲突。
内容的提问来源于stack exchange,提问作者Noah
相关产品推荐
相关产品推荐

