如何解决在ansible中使用json_query组合属性值
我想使用 ansible 中的 json_query 将两个属性组合成由分隔符分隔的单个字符串
示例数据
{
"locations": [
{"name": "Seattle","state": "WA"},{"name": "New York","state": "NY"},{"name": "Bellevue",{"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",{
"name": "Olympia","state": "WA"
}
]
更新: 我能够通过反复试验的方法获得预期的结果,这些是我的发现:
[?state == 'WA'].[join('-',[name,state])][]
Output:
[
"Seattle-WA","Olympia-WA"
]
另外,如果您提供的输入是 unicode 格式,我建议您添加如下所示的 to_json | from_json
表达式:
selected_cities: "{{ test.locations| to_json | from_json | json_query(\"[?state == 'WA'].[join('-',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])') }}"
失败
味精:|- json_query 过滤器插件中的 JMESPathError: 在函数 join() 中,值的无效类型:西雅图,应为:['array-string'] 之一,收到:“AnsibleUnicode”
to_json|from_json 解决方法
引用自json_query: Add examples for starts_with and contains #72821
寄存器变量返回的数据结构需要使用to_json解析| from_json 以获得正确的结果。修正:ansible-collections/community.general#320
- debug:
msg: "{{ locations|to_json|from_json|
json_query('[].join(`-`,state])') }}"
给予
msg:
- Seattle-WA
- New York-NY
- Bellevue-WA
- Olympia-WA
,
只是为了采用纯粹的 JMESPath 方式,因为您的反复试验解决方案仍然具有不必要的额外复杂层。
当你在做
[?state == 'WA'].[join('-',state])][]
您正在创建一个数组 [join('-',state])]
,然后无缘无故地将其展平 []
。
您可以使用更短的方法找到解决方案:
[?state == `WA`].join(`-`,state])
还请注意,您可以使用以下方法克服 JMESPath 查询中的引号(简单或双引号)复杂性:
-
YAML 多行字符串:How do I break a string in YAML over multiple lines?
-
JMESPath 查询中的反引号,如文档中所述:
在上面的示例中,使用反引号引用文字可以避免转义引号并保持可读性。
所以你最终得到(如果你使用的是 Ansible 版本
- debug:
msg: >-
{{ test.locations
| json_query('[?state == `WA`].join(`-`,state])') }}
请注意:正如 @Vladimir Botka 在 2.10 之前的版本中提出的那样,您将受到以下问题的影响:https://github.com/ansible/ansible/issues/27299#issuecomment-331068246,强制您添加 {{1 }} 过滤列表。
给定剧本:
| to_json | from_json
这产生:
- hosts: all
gather_facts: yes
tasks:
- debug:
msg: >-
{{ test.locations
| json_query('[?state == `WA`].join(`-`,state])')
}}
vars:
test:
locations:
- name: Seattle
state: WA
- name: New York
state: NY
- name: Bellevue
state: WA
- name: Olympia
state: WA
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。