在ansible中使用json_query组合属性值
Combine attribute value using json_query in ansible
我想使用 ansible 中的 json_query 将两个属性组合成由定界符分隔的单个字符串
示例数据
{
"locations": [
{"name": "Seattle", "state": "WA"},
{"name": "New York", "state": "NY"},
{"name": "Bellevue", "state": "WA"},
{"name": "Olympia", "state": "WA"}
]
}
如上面的数据集所示,我正在尝试过滤状态“WA”并且执行的输出是:
[
"Seattle-WA",
"Bellevue-WA",
"Olympia-WA"
]
我目前尝试过的:
- debug:
msg: "{{ chart_list.HELM_CHARTS | json_query(\"[?state == 'WA'].{name:name,state:state}\") }}"
Output:
[
{
"name": "Seattle",
"state": "WA"
},
{
"name": "Bellevue",
"state": "WA"
},
{
"name": "Olympia",
"state": "WA"
}
]
更新:
我能够通过反复试验的方法获得预期的结果,这些是我的发现:
[?state == 'WA'].[join('-',[name,state])][]
Output:
[
"Seattle-WA",
"Bellevue-WA",
"Olympia-WA"
]
此外,如果您提供的输入是 unicode 格式,我建议您添加 to_json | from_json
表达式,如下所述:
selected_cities: "{{ test.locations| to_json | from_json | json_query(\"[?state == 'WA'].[join('-',[name,state])][]\") }}"
使用上面的表达式将消除在使用值时或在任何情况下的 unicode 错误。
查看 JMESPath 站点以获取有关 json_query 的更多详细信息,这对解决问题很有帮助。
例如
- debug:
msg: "{{ locations|
json_query('[?state == `WA`].[name,state]')|
map('join', '-')|list }}"
给予
msg:
- Seattle-WA
- Bellevue-WA
- Olympia-WA
同样的结果给出了下面仅使用 Jinja2 过滤器的任务
- debug:
msg: "{{ _names|zip(_states)|map('join', '-')|list }}"
vars:
_locations: "{{ locations|selectattr('state', 'eq', 'WA')|list }}"
_names: "{{ _locations|map(attribute='name')|list }}"
_states: "{{ _locations|map(attribute='state')|list }}"
json_query 问题(已在 2.10 及更高版本中修复)
有 JMESPath join。遗憾
- debug:
msg: "{{ locations|
json_query('[].join(`-`, [name,state])') }}"
失败
msg: |-
JMESPathError in json_query filter plugin:
In function join(), invalid type for value: Seattle, expected one of: ['array-string'], received: "AnsibleUnicode"
to_json|from_json 解决方法
引用自json_query: Add examples for starts_with and contains #72821
data structure returned from register variables needs to be parsed using to_json | from_json in order to get a correct result. Fixes: ansible-collections/community.general#320
- debug:
msg: "{{ locations|to_json|from_json|
json_query('[].join(`-`, [name,state])') }}"
给予
msg:
- Seattle-WA
- New York-NY
- Bellevue-WA
- Olympia-WA
只是为了采用纯 JMESPath 方法,因为您的试错解决方案仍然具有不必要的额外复杂层。
当你在做的时候
[?state == 'WA'].[join('-', [name, state])][]
您正在创建一个数组 [join('-', [name, state])]
然后无缘无故地展开它 []
。
您可以使用更简短的方法找到解决方案:
[?state == `WA`].join(`-`, [name, state])
另请注意,您可以使用以下方法克服 JMESPath 查询的引号中的引号(单引号或双引号)复杂性:
YAML 多行字符串:How do I break a string in YAML over multiple lines?
JMESPath 查询中的反引号,如文档中所述:
In the example above, quoting literals using backticks avoids escaping quotes and maintains readability.
所以你最终得到(如果你使用的是 < 2.10 的 Ansible 版本,请参阅下面的注释):
- debug:
msg: >-
{{ test.locations
| json_query('[?state == `WA`].join(`-`, [name, state])') }}
请注意:如 @Vladimir Botka on the versions prior to 2.10, you will be affected by this issue: https://github.com/ansible/ansible/issues/27299#issuecomment-331068246 所述,强制您在列表中添加 | to_json | from_json
过滤器。
鉴于剧本:
- hosts: all
gather_facts: yes
tasks:
- debug:
msg: >-
{{ test.locations
| json_query('[?state == `WA`].join(`-`, [name, state])')
}}
vars:
test:
locations:
- name: Seattle
state: WA
- name: New York
state: NY
- name: Bellevue
state: WA
- name: Olympia
state: WA
这产生:
[
"Seattle-WA",
"Bellevue-WA",
"Olympia-WA"
]
我想使用 ansible 中的 json_query 将两个属性组合成由定界符分隔的单个字符串
示例数据
{
"locations": [
{"name": "Seattle", "state": "WA"},
{"name": "New York", "state": "NY"},
{"name": "Bellevue", "state": "WA"},
{"name": "Olympia", "state": "WA"}
]
}
如上面的数据集所示,我正在尝试过滤状态“WA”并且执行的输出是:
[
"Seattle-WA",
"Bellevue-WA",
"Olympia-WA"
]
我目前尝试过的:
- debug:
msg: "{{ chart_list.HELM_CHARTS | json_query(\"[?state == 'WA'].{name:name,state:state}\") }}"
Output:
[
{
"name": "Seattle",
"state": "WA"
},
{
"name": "Bellevue",
"state": "WA"
},
{
"name": "Olympia",
"state": "WA"
}
]
更新: 我能够通过反复试验的方法获得预期的结果,这些是我的发现:
[?state == 'WA'].[join('-',[name,state])][]
Output:
[
"Seattle-WA",
"Bellevue-WA",
"Olympia-WA"
]
此外,如果您提供的输入是 unicode 格式,我建议您添加 to_json | from_json
表达式,如下所述:
selected_cities: "{{ test.locations| to_json | from_json | json_query(\"[?state == 'WA'].[join('-',[name,state])][]\") }}"
使用上面的表达式将消除在使用值时或在任何情况下的 unicode 错误。 查看 JMESPath 站点以获取有关 json_query 的更多详细信息,这对解决问题很有帮助。
例如
- debug:
msg: "{{ locations|
json_query('[?state == `WA`].[name,state]')|
map('join', '-')|list }}"
给予
msg:
- Seattle-WA
- Bellevue-WA
- Olympia-WA
同样的结果给出了下面仅使用 Jinja2 过滤器的任务
- debug:
msg: "{{ _names|zip(_states)|map('join', '-')|list }}"
vars:
_locations: "{{ locations|selectattr('state', 'eq', 'WA')|list }}"
_names: "{{ _locations|map(attribute='name')|list }}"
_states: "{{ _locations|map(attribute='state')|list }}"
json_query 问题(已在 2.10 及更高版本中修复)
有 JMESPath join。遗憾
- debug:
msg: "{{ locations|
json_query('[].join(`-`, [name,state])') }}"
失败
msg: |- JMESPathError in json_query filter plugin: In function join(), invalid type for value: Seattle, expected one of: ['array-string'], received: "AnsibleUnicode"
to_json|from_json 解决方法
引用自json_query: Add examples for starts_with and contains #72821
data structure returned from register variables needs to be parsed using to_json | from_json in order to get a correct result. Fixes: ansible-collections/community.general#320
- debug:
msg: "{{ locations|to_json|from_json|
json_query('[].join(`-`, [name,state])') }}"
给予
msg:
- Seattle-WA
- New York-NY
- Bellevue-WA
- Olympia-WA
只是为了采用纯 JMESPath 方法,因为您的试错解决方案仍然具有不必要的额外复杂层。
当你在做的时候
[?state == 'WA'].[join('-', [name, state])][]
您正在创建一个数组 [join('-', [name, state])]
然后无缘无故地展开它 []
。
您可以使用更简短的方法找到解决方案:
[?state == `WA`].join(`-`, [name, state])
另请注意,您可以使用以下方法克服 JMESPath 查询的引号中的引号(单引号或双引号)复杂性:
YAML 多行字符串:How do I break a string in YAML over multiple lines?
JMESPath 查询中的反引号,如文档中所述:
In the example above, quoting literals using backticks avoids escaping quotes and maintains readability.
所以你最终得到(如果你使用的是 < 2.10 的 Ansible 版本,请参阅下面的注释):
- debug:
msg: >-
{{ test.locations
| json_query('[?state == `WA`].join(`-`, [name, state])') }}
请注意:如 @Vladimir Botka on the versions prior to 2.10, you will be affected by this issue: https://github.com/ansible/ansible/issues/27299#issuecomment-331068246 所述,强制您在列表中添加 | to_json | from_json
过滤器。
鉴于剧本:
- hosts: all
gather_facts: yes
tasks:
- debug:
msg: >-
{{ test.locations
| json_query('[?state == `WA`].join(`-`, [name, state])')
}}
vars:
test:
locations:
- name: Seattle
state: WA
- name: New York
state: NY
- name: Bellevue
state: WA
- name: Olympia
state: WA
这产生:
[
"Seattle-WA",
"Bellevue-WA",
"Olympia-WA"
]