You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 09:57:32