Ansible如何将文件行转换为指定结构字典?求简洁实现方案
优化Ansible数据转换的实现方案
嘿,你当前的代码问题很明确——它把每个name和attributes拆成了独立的字典条目,而不是把同一个item的两个属性合并到一起。咱们可以通过调整逻辑或者结合Ansible自带的过滤器,把代码改得更清晰易读。
方法一:优化Jinja2逻辑(最稳妥直观)
我们可以跟踪当前处理的分类和item:每遇到name=行就新建一个item字典,后续的attributes=行直接把属性追加到这个item里,最后再把item加入对应分类的列表。逻辑线性,读起来一目了然:
- set_fact: converted_data: >- {%- set res = {} -%} {%- set current_category = None -%} {%- set current_item = None -%} {%- for line in content.stdout_lines -%} {%- set parts = line.split(' ', 1) -%} {%- set cat = parts[0] -%} {%- set key, val = parts[1].split('=') -%} {%- if cat != current_category -%} {%- set current_category = cat -%} {%- if res.get(cat) is not defined -%} {%- set _ = res.update({cat: []}) -%} {%- endif -%} {%- set current_item = None -%} {%- endif -%} {%- if key == 'name' -%} {%- set current_item = {'name': val} -%} {%- set _ = res[cat].append(current_item) -%} {%- elif key == 'attributes' and current_item is not none -%} {%- set attrs = val.split(',') | map('trim') | list -%} {%- set _ = current_item.update({'attributes': attrs}) -%} {%- endif -%} {%- endfor -%} {{ res }}
这个写法的优势是:
- 明确跟踪当前上下文(哪个分类、哪个item),不会出现属性错位的问题
- 代码步骤清晰,后续维护的时候一眼就能看懂每一步在做什么
方法二:结合过滤器(适合格式严格的场景)
如果你的源文件格式是每个item的name行和attributes行严格连续(比如category1 name=item1紧接着就是category1 attributes=...),可以用batch(2)把行两两分组,再结合groupby聚合,代码更简洁:
- set_fact: converted_data: >- {%- set temp_items = [] -%} {%- for line_pair in content.stdout_lines | batch(2) -%} {%- set name_part = line_pair[0].split(' ', 1) -%} {%- set attr_part = line_pair[1].split(' ', 1) -%} {%- set item = { 'category': name_part[0], 'name': name_part[1].split('=')[1], 'attributes': attr_part[1].split('=')[1].split(',') | map('trim') | list } -%} {%- set _ = temp_items.append(item) -%} {%- endfor -%} {{ temp_items | groupby('category') | items2dict(key_name='0', value_name='1') | map('combine', {'value': item | map('omit', 'category') | list}) | items2dict }}
不过这个方法依赖文件格式的严格性,如果源文件可能出现换行错乱的情况,还是第一种方法更靠谱。
最终效果
调整后的代码会生成你想要的结构:
category1: - name: item1 attributes: [attr1, attr2] - name: item2 attributes: [attr1, attr2, attr3] category2: - name: item1 attributes: [attr1]
内容的提问来源于stack exchange,提问作者Moon
相关产品推荐
相关产品推荐

