如果键的值与变量(字符串)匹配,我一直无法获取特定的 json 对象。
我的 json 文件如下所示:
"totalRecordsWithoutPaging": 1234,
"jobs": [
{
"jobSummary": {
"totalNumOfFiles": 0,
"jobId": 8035,
"destClientName": "BOSDEKARLSSP010",
"destinationClient": {
"clientId": 10,
"clientName": "BOSDEKARLSSP010"
}
}
},
{
"jobSummary": {
"totalNumOfFiles": 0,
"jobId": 9629,
"destClientName": "BOSDEKARLSSP006",
"destinationClient": {
"clientId": 11,
"clientName": "BOSDEKARLSSP006"
}
}
},
.....
]
}
我用
result: "{{ lookup('file','CVExport-short.json') | from_json }}"
阅读了这个 json我只能得到 destClientName
的一个值使用以下代码键:- name: Iterate JSON
set_fact:
app_item: "{{ item.jobSummary }}"
with_items: "{{ result.jobs }}"
register: app_result
- debug:
var: app_result.results[0].ansible_facts.app_item.destClientName
我的目标是获得
jobId
的值如果 destClientName
的值匹配任何 jobSummary
中的一些其他变量或字符串.我仍然对 Ansible 了解不多。因此,任何帮助将不胜感激。
更新
好的,我找到了一种解决方案。
- name: get job ID
set_fact:
job_id: "{{ item.jobSummary.jobId }}"
with_items: "{{ result.jobs}}"
when: item.jobSummary.destClientName == '{{ target_vm }}'
- debug:
msg: "{{job_id}}"
但我认为可能有比这更好的解决方案。知道怎么做吗?
最佳答案
Ansible 的 json_query filter 让您通过应用 JMESPath 对 JSON 文档执行复杂的过滤。表达式。无需循环遍历结果中的作业,您只需一步即可获得所需的信息。
我们要查询所有具有 destClientName
的作业与 target_vm
中的值匹配.使用文字值,产生该作业列表的表达式将如下所示:
jobs[?jobSummary.destClientName == `BOSDEKARLSSP006`]
当应用于您的样本数据时,其结果将是:[
{
"jobSummary": {
"totalNumOfFiles": 0,
"jobId": 9629,
"destClientName": "BOSDEKARLSSP006",
"destinationClient": {
"clientId": 11,
"clientName": "BOSDEKARLSSP006"
}
}
}
]
从此结果中,您想提取 jobId
,所以我们将表达式改写如下:jobs[?jobSummary.destClientName == `BOSDEKARLSSP006`]|[0].jobSummary.jobId
这给了我们:9629
要在剧本中进行这项工作,您需要将此表达式中的文字主机名替换为 target_vm
的值。多变的。这是演示解决方案的完整剧本:---
- hosts: localhost
gather_facts: false
# This is just the sample data from your question.
vars:
target_vm: BOSDEKARLSSP006
results:
totalRecordsWithoutPaging: 1234
jobs:
- jobSummary:
totalNumOfFiles: 0
jobId: 8035
destClientName: BOSDEKARLSSP010
destinationClient:
clientId: 10
clientName: BOSDEKARLSSP010
- jobSummary:
totalNumOfFiles: 0
jobId: 9629
destClientName: BOSDEKARLSSP006
destinationClient:
clientId: 11
clientName: BOSDEKARLSSP006
tasks:
- name: get job ID
set_fact:
job_id: "{{ results|json_query('jobs[?jobSummary.destClientName == `{}`]|[0].jobSummary.jobId'.format(target_vm)) }}"
- debug:
var: job_id
更新 回复:你的评论
{}
在表达式中是一个 Python 字符串格式化序列通过调用
.format(target_vm)
填写.在 Python 中,表达:
'The quick brown {} jumped over the lazy {}.'.format('fox', 'dog')
将评估为:The quick brown fox jumped over the lazy dog.
这正是我们在 set_fact
中所做的。表达。一世可以改为:
job_id: "{{ results|json_query('jobs[?jobSummary.destClientName == `' ~ target_vm ~ '`]|[0].jobSummary.jobId') }}"
(其中 ~
是 Jinja 字符串化连接运算符)
关于json - 在 Ansible 中循环 json 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56323549/