我有这样的输入
ok: [localhost] => {
"static_plugin_versions": [
{
"name": "ace-editor",
"version": "1.1"
},
{
"name": "analysis-core",
"version": "1.95"
},
{
"name": "ant",
"version": "1.9"
},
{
"name": "antisamy-markup-formatter",
"version": "1.5"
},
{
"name": "apache-httpcomponents-client-4-api",
"version": "4.5.5-3.0"
}
]
}
我的目标是通过指定一个特定的名称打印出version
。在这种情况下,专门寻找version
的analysis-core
我试过的是以下内容
- debug:
var: static_plugin_versions['analysis-core']['version']
- debug:
var: static_plugin_versions['analysis-core'].version
- debug:
var: static_plugin_versions[analysis-core.version]
唯一有效的是
- debug:
var: static_plugin_versions[1].version
但这是不可行的,因为如果将更多条目添加到字典中,它将会中断。
任何迹象表明我在这里做错了什么。我正在寻找一种不依赖于循环的方式。
编辑
试过这个
- set_fact:
analysis_core_version: "{{ item.version }}"
when: "'analysis-core' in item.name"
with_items: "{{ static_plugin_versions }}"
- debug:
var: analysis-core-version
但我得到:
TASK [copy : set_fact] *******************************************************************************************************************************************************************************************************************************************************************************************************
skipping: [localhost] => (item={u'version': u'1.1', u'name': u'ace-editor'})
ok: [localhost] => (item={u'version': u'1.95', u'name': u'analysis-core'})
skipping: [localhost] => (item={u'version': u'1.9', u'name': u'ant'})
skipping: [localhost] => (item={u'version': u'1.5', u'name': u'antisamy-markup-formatter'})
skipping: [localhost] => (item={u'version': u'4.5.5-3.0', u'name': u'apache-httpcomponents-client-4-api'})
TASK [copy : debug] **********************************************************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"analysis-core-version": "VARIABLE IS NOT DEFINED!"
}
最简单的方法是使用selectattr过滤器,它允许您将过滤器应用于对象列表。例如,如果我有这个剧本:
---
- hosts: localhost
gather_facts: false
vars:
"static_plugin_versions": [
{
"name": "ace-editor",
"version": "1.1"
},
{
"name": "analysis-core",
"version": "1.95"
},
{
"name": "ant",
"version": "1.9"
},
{
"name": "antisamy-markup-formatter",
"version": "1.5"
},
{
"name": "apache-httpcomponents-client-4-api",
"version": "4.5.5-3.0"
}
]
tasks:
- debug:
msg: "version of {{ item }} is {{ (static_plugin_versions|selectattr('name', 'eq', item)|first).version }}"
loop:
- ace-editor
输出将是:
TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => (item=ace-editor) => {
"msg": "version of ace-editor is 1.1"
}
或者,使用您的示例:
- set_fact:
analysis_core_version: "{{ (static_plugin_versions|selectattr('name', 'eq', 'analysis-core')|first).version }}"
- debug:
var: analysis-core-version
哪个产生:
ok: [localhost] => {
"analysis_core_version": "1.95"
}
如有必要,json_query过滤器允许更复杂的查询。
正如Illias评论所建议的那样,您可以使用循环来遍历列表中的其他每个元素,匹配其name
值并在满足条件时打印其version
。
- name: print version of analysis-core
debug:
msg: "{{ item.version }}"
when: item.name == 'analysis-core'
loop: "{{ static_plugin_versions }}"
同时,只要没有匹配,这将转到其他每个元素并跳过任务。如果你有数百个插件,这将很快在你的ansible执行日志中变得不可读。
查询您的数据结构以获得您所需的确切内容。你的朋友在这里是json_query
filter(如果你想进一步,你应该阅读jmespath doc)。对于你的特定例子
- name: print version of analysis-core
debug:
msg: >-
{{ (static_plugin_versions | json_query("[?name == 'analysis-core'].version")).0 }}
笔记: