json - 在 Ansible 中循环 json 对象

标签 json loops ansible

如果键的值与变量(字符串)匹配,我一直无法获取特定的 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/

相关文章:

excel - 更有效的方法来复制函数 VBA/Excel

ansible - 从输入文件/变量循环ansible ec2主机名

macos - 使用 ec2.py 进行动态库存

java - 带有 javac "-parameters"的 JSON ObjectMapper 在通过 maven 而不是通过 IntelliJ IDEA 运行时的行为

java - REST 网络服务 : Server responding with a JAX-B error to GET

python - jinja2 for ... if 循环中的第一个 x 项

tags - Ansible-默认/显式标签

python - 如何处理json空值

c# - 反序列化从 node.js (azure sdk) 发送的 Azure ServiceBus 队列消息时出错

r - 使用循环或应用覆盖多个字符串变量