使用 jmespath 连接复杂数据结构中的多个数组

join multiple arrays in complex data structure with jmespath

我正在尝试将复杂数据结构中描述的 NFS 导出 转换为 nfs-server 守护程序接受的配置选项,稍后将在 ansible 中使用.

我有:

    nfs_exports:
    - path: /export/home
      state: present
      options:
      - clients: "192.168.0.0/24"
        permissions:
        - "rw"
        - "sync"
        - "no_root_squash"
        - "fsid=0"
    - path: /export/public
      state: present
      options:
      - clients: "192.168.0.0/24"
        permissions:
        - "rw"
        - "sync"
        - "root_squash"
        - "fsid=0"
      - clients: "*"
        permissions:
        - "ro"
        - "async"
        - "all_squash"
        - "fsid=1"

必须变成:

        [
            {
                "options": "192.168.0.0/24(rw,sync,no_root_squash,fsid=0)",
                "path": "/export/home",
                "state": "present"
            },
            {
                "options": "192.168.0.0/24(rw,sync,root_squash,fsid=0) *(ro,async,all_squash,fsid=1)",
                "path": "/export/public",
                "state": "present"
            }
        ]

到目前为止,我可以使用 {{ nfs_exports | json_query(query) }}

query: "[].{path:path,state:state,options:options.join(` `,[].join(``,[clients,`(`,join(`,`,permissions),`)`]))}"

得到

{
        "options": "192.168.0.0/24(rw,sync,no_root_squash,fsid=0)",
        "path": "/export/home",
        "state": "present"
},
{
        "options": "192.168.0.0/24(rw,sync,root_squash,fsid=0)*(ro,async,all_squash,fsid=1)",
        "path": "/export/public",
        "state": "present"
}

这可能很简单,但我无法通过最后一个选项加入,space ' ' 被删除。 因此,如果有人知道正确的查询,将不胜感激。

鉴于查询:

[].{ path: path, state: state, options: join(' ', options[].join('', [clients, '(', join(',', permissions), ')'])) }

在JSON

{
  "nfs_exports": [
    {
      "path": "/export/home",
      "state": "present",
      "options": [
        {
          "clients": "192.168.0.0/24",
          "permissions": [
            "rw",
            "sync",
            "no_root_squash",
            "fsid=0"
          ]
        }
      ]
    },
    {
      "path": "/export/public",
      "state": "present",
      "options": [
        {
          "clients": "192.168.0.0/24",
          "permissions": [
            "rw",
            "sync",
            "root_squash",
            "fsid=0"
          ]
        },
        {
          "clients": "*",
          "permissions": [
            "ro",
            "async",
            "all_squash",
            "fsid=1"
          ]
        }
      ]
    }
  ]
}

它会给你预期的输出:

[
  {
    "path": "/export/home",
    "state": "present",
    "options": "192.168.0.0/24(rw,sync,no_root_squash,fsid=0)"
  },
  {
    "path": "/export/public",
    "state": "present",
    "options": "192.168.0.0/24(rw,sync,root_squash,fsid=0) *(ro,async,all_squash,fsid=1)"
  }
]

请注意:字符串乱码 `` 不适用于 space 字符串,因为正如文档中指出的那样,它将被解析作为 JSON:

A literal expression is an expression that allows arbitrary JSON objects to be specified

来源:https://jmespath.org/specification.html#literal-expressions


当你到达以下点时,这很容易:

[].{ path: path, state: state, options: options[].join('', [clients, '(', join(',', permissions), ')']) }

你似乎已经实现了这一点,这给了

[
  {
    "path": "/export/home",
    "state": "present",
    "options": [
      "192.168.0.0/24(rw,sync,no_root_squash,fsid=0)"
    ]
  },
  {
    "path": "/export/public",
    "state": "present",
    "options": [
      "192.168.0.0/24(rw,sync,root_squash,fsid=0)",
      "*(ro,async,all_squash,fsid=1)"
    ]
  }
]

因为您只剩下用 space 作为粘合字符连接 options 中的整个数组。