【问题标题】:Get specific list of dict from json content using Ansible使用 Ansible 从 json 内容中获取特定的 dict 列表
【发布时间】:2021-03-08 03:07:32
【问题描述】:

我花了很多时间终于没有得到我需要的东西,我的要求是如此复杂,所以我更愿意与你分享我的担忧::

我有这个 json.content 来解析它:


        "json": {
            "content": [
                {
                    "name": "machine1",
                    "hasChildren": false,
                    "resourceData": {
                        "entries": [
                            {
                                "value": {
                                    "type": "string",
                                    "value": "Red Hat Enterprise Linux 7 (64-bit)"
                                },
                                "key": "MachineGuestOperatingSystem"
                            },
                            {
                                "value": {
                                    "type": "string",
                                    "value": "Folder1"
                                },
                                "key": "VMware.VirtualCenter.Folder"
                            },
                            {
                                "value": {
                                    "type": "boolean",
                                    "value": true
                                },
                                "key": "Destroy"
                            }
                        ]
                    }
                },
                {

                    "name": "machine2",
                    "hasChildren": false,
                    "resourceData": {
                        "entries": [
                            {
                                "value": {
                                    "type": "string",
                                    "value": "Red Hat Enterprise Linux 7 (64-bit)"
                                },
                                "key": "MachineGuestOperatingSystem"
                            },
                            {
                                "value": {
                                    "type": "string",
                                    "value": "Folder2"
                                },
                                "key": "VMware.VirtualCenter.Folder"
                            },
                            {
                                "value": {
                                    "type": "boolean",
                                    "value": false
                                },
                                "key": "Destroy"
                            }
                        ]
                    }
                },
                {
                    "name": "machine3",
                    "hasChildren": false,
                    "resourceData": {
                        "entries": [
                            {
                                "value": {
                                    "type": "string",
                                    "value": "Windows Server 2016 or later (64-bit)"
                                },
                                "key": "MachineGuestOperatingSystem"
                            },
                            {
                                "value": {
                                    "type": "string",
                                    "value": "Folder3"
                                },
                                "key": "VMware.VirtualCenter.Folder"
                            },
                            {
                                "value": {
                                    "type": "boolean",
                                    "value": true
                                },
                                "key": "Destroy"
                            }
                        ]
                    }
                }
            ]
        }


我想输出类似的东西:

[{"name":"machine1", "OsName": "Red Hat Enterprise Linux 7 (64-bit)", "Folder": "Folder1"}, {"name":"machine2", "OsName": "Red Hat Enterprise Linux 7 (64-bit)", "Folder": "Folder2"},
{"name":"machine3", "OsName": "Windows Server 2016 or later (64-bit)", "Folder": "Folder3"}]

我尝试了所有解决方案,但没有办法,所有结果都不是我想要的。有人可以帮我找到一个解决方案来获得这个出席的结果

【问题讨论】:

    标签: json list ansible


    【解决方案1】:

    下面的任务完成了这项工作

        - set_fact:
            _list: "{{ json.content|json_query(query) }}"
          vars:
            query: "[].{name: name,
                        OsName: resourceData.entries[0].value.value,
                        Folder: resourceData.entries[1].value.value}"
    

    给予

      _list:
      - Folder: Folder1
        OsName: Red Hat Enterprise Linux 7 (64-bit)
        name: machine1
      - Folder: Folder2
        OsName: Red Hat Enterprise Linux 7 (64-bit)
        name: machine2
      - Folder: Folder3
        OsName: Windows Server 2016 or later (64-bit)
        name: machine
    

    问:"改变了(key, value)的顺序,所以用[0]和[1]引用会不一样。"

    A:通过按键选择项目。您必须pipe 结果并选择所选列表的第一项,例如下面的任务给出了相同的结果

        - set_fact:
            _list: "{{ json.content|json_query(query) }}"
          vars:
            query: "[].{name: name,
                        OsName: resourceData.entries[?key==`MachineGuestOperatingSystem`].value.value|[0],
                        Folder: resourceData.entries[?key==`VMware.VirtualCenter.Folder`].value.value|[0]}"
    

    问:过滤 'Red Hat ...' 获取输出

      - Folder: Folder1
        OsName: Red Hat Enterprise Linux 7 (64-bit)
        name: machine1
      - Folder: Folder2
        OsName: Red Hat Enterprise Linux 7 (64-bit)
        name: machine2
    

    A:使用 selectattr,例如下面的任务完成了这项工作

        - debug:
            msg: "{{ _list|
                     selectattr('OsName', 'eq', 'Red Hat Enterprise Linux 7 (64-bit)')|
                     list }}"
    

    问:我可以在哪里学习这种搜索?

    答:JMESPath Specification 中有例子。作为提示,请参阅下面的代码,了解如何将这些示例转换为 Ansible json_query

    Example1

        - name: 'search(foo, {"foo": "value"}) -> "value"'
          debug:
            msg: "{{ _dict|json_query(_query) }}"
          vars:
            _dict: {"foo": "value"}
            _query: "foo"
    

    Example2

        - name: 'search(foo[?bar==`10`], {"foo": [{"bar": 1}, {"bar": 10}]}) -> [{"bar": 10}]'
          debug:
            msg: "{{ _dict|json_query(_query) }}"
          vars:
            _dict: {"foo": [{"bar": 1}, {"bar": 10}]}
            _query: "foo[?bar==`10`]"
    

    Example3

        - name: 'search(foo | bar, {"foo": {"bar": "baz"}}) -> "baz"'
          debug:
            msg: "{{ _dict|json_query(_query) }}"
          vars:
            _dict: {"foo": {"bar": "baz"}}
            _query: "foo | bar"
    

    【讨论】:

    • 感谢您的快速回复,您给了我一个希望,但是在条目中有数千个条目并且它以某种方式改变了 (key, value) 的顺序,因此通过 [0] 或[1] 每次运行的剧本都不相同。
    • 不客气。通过键选择项目。我已经更新了答案。
    • 我已经测试过了,效果很好,非常感谢。
    • 如果你能给我一个我可以学习这种搜索的来源,我将不胜感激,只要一个链接对我有用,我可以学习如何通过 json 进行复杂的搜索使用 ansible
    • 我添加了一些示例。除此之外,看看我的项目Ansible examples。搜索 json_query(示例 2,20,43,69,140,​​267,...)。
    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 2019-12-21
    • 2021-06-06
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多