使用 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
中的整个数组。
我正在尝试将复杂数据结构中描述的 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
中的整个数组。