Json 如何使用JQ访问父字典密钥

Json 如何使用JQ访问父字典密钥,json,jq,Json,Jq,我正在尝试使用JQ从docker inspect输出JSON片段。。。包括所有网络的详细信息。问题是网络的编号和名称各不相同 如果您共享了一个代码段,如果这有帮助 我的第一次尝试是有效的,因为我明确地命名了每个网络、入口和webnet。我希望我的最终解决方案是不要在过滤器中提及网络名称,而是将它们包含在输出中 jq '.[] | { Networks: (.NetworkSettings .Networks | {ingress: .ingress .IPAddress, webnet: .we

我正在尝试使用JQ从docker inspect输出JSON片段。。。包括所有网络的详细信息。问题是网络的编号和名称各不相同

如果您共享了一个代码段,如果这有帮助

我的第一次尝试是有效的,因为我明确地命名了每个网络、入口和webnet。我希望我的最终解决方案是不要在过滤器中提及网络名称,而是将它们包含在输出中

jq '.[] | { Networks: (.NetworkSettings .Networks | {ingress: .ingress .IPAddress, webnet: .webnet .IPAddress})}' 
{
  "Networks": {
    "ingress": "10.255.0.5",
    "webnet": "10.0.0.3"
  }
}
"ingress"
"webnet"
{
  "Name": "/nginx.1.attiwcma8h39wclpsncp608tk",
  "Id": "f2ee9caae862326a7a62304659121c506f8afb9d74080475702da3595576937a",
  "Path": "nginx",
  "Networks": {
    "ingress": {
      "IPAddress": "10.255.0.5",
      "NetworkID": "zznyce2va5pfggq14su51zygn"
    },
    "webnet": {
      "IPAddress": "10.0.0.3",
      "NetworkID": "g66ea3npnaiwvvdy66rijt5yo"
    }
  }
}
这是输出

jq '.[] | { Networks: (.NetworkSettings .Networks | {ingress: .ingress .IPAddress, webnet: .webnet .IPAddress})}' 
{
  "Networks": {
    "ingress": "10.255.0.5",
    "webnet": "10.0.0.3"
  }
}
"ingress"
"webnet"
{
  "Name": "/nginx.1.attiwcma8h39wclpsncp608tk",
  "Id": "f2ee9caae862326a7a62304659121c506f8afb9d74080475702da3595576937a",
  "Path": "nginx",
  "Networks": {
    "ingress": {
      "IPAddress": "10.255.0.5",
      "NetworkID": "zznyce2va5pfggq14su51zygn"
    },
    "webnet": {
      "IPAddress": "10.0.0.3",
      "NetworkID": "g66ea3npnaiwvvdy66rijt5yo"
    }
  }
}
我做了一些研究,发现我可以将变量分配给我想要的节点,但不能分配给父键

jq '.[] | .NetworkSettings .Networks[] as $parent | { IPAddress: $parent .IPAddress, NetworkID: $parent .NetworkID }'
{
  "IPAddress": "10.255.0.5",
  "NetworkID": "zznyce2va5pfggq14su51zygn"
}
{
  "IPAddress": "10.0.0.3",
  "NetworkID": "g66ea3npnaiwvvdy66rijt5yo"
}
以下是节点的详细信息,但没有父密钥

jq '.[] | .NetworkSettings .Networks[] as $parent | { IPAddress: $parent .IPAddress, NetworkID: $parent .NetworkID }'
{
  "IPAddress": "10.255.0.5",
  "NetworkID": "zznyce2va5pfggq14su51zygn"
}
{
  "IPAddress": "10.0.0.3",
  "NetworkID": "g66ea3npnaiwvvdy66rijt5yo"
}
接下来,我可以访问密钥,但无法访问详细信息

jq '.[] | .NetworkSettings .Networks | keys[] as $key | $key'
这是输出

jq '.[] | { Networks: (.NetworkSettings .Networks | {ingress: .ingress .IPAddress, webnet: .webnet .IPAddress})}' 
{
  "Networks": {
    "ingress": "10.255.0.5",
    "webnet": "10.0.0.3"
  }
}
"ingress"
"webnet"
{
  "Name": "/nginx.1.attiwcma8h39wclpsncp608tk",
  "Id": "f2ee9caae862326a7a62304659121c506f8afb9d74080475702da3595576937a",
  "Path": "nginx",
  "Networks": {
    "ingress": {
      "IPAddress": "10.255.0.5",
      "NetworkID": "zznyce2va5pfggq14su51zygn"
    },
    "webnet": {
      "IPAddress": "10.0.0.3",
      "NetworkID": "g66ea3npnaiwvvdy66rijt5yo"
    }
  }
}
如何将父项名称作为标签访问,并输出子项详细信息?我想我需要像下面这样的东西,但不知道它是否正确或如何到达那里

($key): { IPAddress: $parent[$key] .IPAddress, NetworkID: $parent[$key] .NetworkID }
我的最终解决方案是将多个级别的细节与所有网络的细节结合起来。我想如果我能解决上面的问题,我可以解决下面的问题,但我会把它包括在内,以防它有所帮助

.[] | {Name: .Name, Id: .Id, Path: .Path, Networks: (.NetworkSettings .Networks | {ingress: { IPAddress: .ingress .IPAddress, NetworkID: .ingress .NetworkID }, 
webnet: {IPAddress: .webnet .IPAddress, NetworkID: .webnet .NetworkID}})}
这是输出

jq '.[] | { Networks: (.NetworkSettings .Networks | {ingress: .ingress .IPAddress, webnet: .webnet .IPAddress})}' 
{
  "Networks": {
    "ingress": "10.255.0.5",
    "webnet": "10.0.0.3"
  }
}
"ingress"
"webnet"
{
  "Name": "/nginx.1.attiwcma8h39wclpsncp608tk",
  "Id": "f2ee9caae862326a7a62304659121c506f8afb9d74080475702da3595576937a",
  "Path": "nginx",
  "Networks": {
    "ingress": {
      "IPAddress": "10.255.0.5",
      "NetworkID": "zznyce2va5pfggq14su51zygn"
    },
    "webnet": {
      "IPAddress": "10.0.0.3",
      "NetworkID": "g66ea3npnaiwvvdy66rijt5yo"
    }
  }
}
谢谢,韦斯

以下是您无法访问代码段时的输入

[
    {
        "Id": "f2ee9caae862326a7a62304659121c506f8afb9d74080475702da3595576937a",
        "Created": "2017-08-08T14:17:47.911028584Z",
        "Path": "nginx",
        "Args": [
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 18628,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2017-08-08T14:17:48.299360684Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:b8efb18f159bd948486f18bd8940b56fd2298b438229f5bd2bcf4cedcf037448",
        "ResolvConfPath": "/var/lib/docker/containers/f2ee9caae862326a7a62304659121c506f8afb9d74080475702da3595576937a/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/f2ee9caae862326a7a62304659121c506f8afb9d74080475702da3595576937a/hostname",
        "HostsPath": "/var/lib/docker/containers/f2ee9caae862326a7a62304659121c506f8afb9d74080475702da3595576937a/hosts",
        "LogPath": "/var/lib/docker/containers/f2ee9caae862326a7a62304659121c506f8afb9d74080475702da3595576937a/f2ee9caae862326a7a62304659121c506f8afb9d74080475702da3595576937a-json.log",
        "Name": "/nginx.1.attiwcma8h39wclpsncp608tk",
        "RestartCount": 0,
        "Driver": "overlay",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Dns": null,
            "DnsOptions": null,
            "DnsSearch": null,
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": null,
            "DeviceCgroupRules": null,
            "DiskQuota": 0,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": -1,
            "OomKillDisable": false,
            "PidsLimit": 0,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay/f7e30463365de46a74cbdf5835ad6d5ab6f390a4d53fb42c25b6a43a59cf6910/root",
                "MergedDir": "/var/lib/docker/overlay/6a3ac9fc31cda9ace1b7b02935cb2467be7a97984fe33f01a73706a8eae07968/merged",
                "UpperDir": "/var/lib/docker/overlay/6a3ac9fc31cda9ace1b7b02935cb2467be7a97984fe33f01a73706a8eae07968/upper",
                "WorkDir": "/var/lib/docker/overlay/6a3ac9fc31cda9ace1b7b02935cb2467be7a97984fe33f01a73706a8eae07968/work"
            },
            "Name": "overlay"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "f2ee9caae862",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.13.3-1~stretch",
                "NJS_VERSION=1.13.3.0.1.11-1~stretch"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "ArgsEscaped": true,
            "Image": "nginx:latest@sha256:788fa27763db6d69ad3444e8ba72f947df9e7e163bad7c1f5614f8fd27a311c3",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "com.docker.swarm.node.id": "3hq6jrjhs4ndk5lffpg52xj13",
                "com.docker.swarm.service.id": "w787z4alcw4t3p0nesgwhj1yn",
                "com.docker.swarm.service.name": "nginx",
                "com.docker.swarm.task": "",
                "com.docker.swarm.task.id": "attiwcma8h39wclpsncp608tk",
                "com.docker.swarm.task.name": "nginx.1.attiwcma8h39wclpsncp608tk"
            },
            "StopSignal": "SIGTERM"
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "66e098ef6e1bea3b2f66dcc7460eab9fc23436cb39836918a46e1d38692a55cb",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/66e098ef6e1b",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "ingress": {
                    "IPAMConfig": {
                        "IPv4Address": "10.255.0.5"
                    },
                    "Links": null,
                    "Aliases": [
                        "f2ee9caae862"
                    ],
                    "NetworkID": "zznyce2va5pfggq14su51zygn",
                    "EndpointID": "09b287a8d82e85d0790a8ea8634e97844481cb478ded89f6ac1dfda7e3c31f76",
                    "Gateway": "",
                    "IPAddress": "10.255.0.5",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:0a:ff:00:05",
                    "DriverOpts": null
                },
                "webnet": {
                    "IPAMConfig": {
                        "IPv4Address": "10.0.0.3"
                    },
                    "Links": null,
                    "Aliases": [
                        "f2ee9caae862"
                    ],
                    "NetworkID": "g66ea3npnaiwvvdy66rijt5yo",
                    "EndpointID": "46b7ef9ba2d82cf56f34ade3a80a094b5f92f05d5e9051dab0542e2992298bb2",
                    "Gateway": "",
                    "IPAddress": "10.0.0.3",
                    "IPPrefixLen": 24,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:0a:00:00:03",
                    "DriverOpts": null
                }
            }
        }
    }
]

这是您最初使用固定网络密钥的解决方案,只需稍微重新格式化即可

    .[]
  | {
       Name: .Name,
       Id:   .Id,
       Path: .Path,
       Networks: (
            .NetworkSettings.Networks
          | {
             ingress: { IPAddress: .ingress.IPAddress, NetworkID:.ingress.NetworkID }, 
             webnet:  { IPAddress: .webnet.IPAddress,  NetworkID:.webnet.NetworkID  }
          }
       )
     }
这里有一个更通用的解决方案,它使用reduce和keys来构造Networks对象

    .[]
  | {
       Name: .Name,
       Id:   .Id,
       Path: .Path,
       Networks: (
            .NetworkSettings.Networks as $n
          | reduce ($n|keys[]) as $k (
               {}
             ; .[$k] = ( $n[$k] | {IPAddress, NetworkID} )
            )
       )
     }
使用|=来更新网络,而不是构造新对象,可以稍微简化

    .[]
  | {
       Name: .Name,
       Id:   .Id,
       Path: .Path,
       Networks: (
            .NetworkSettings.Networks
          | reduce keys[] as $k (
               .
             ; .[$k] |= {IPAddress, NetworkID}
            )
       )
     }

谢谢它给了我想要的结果,但我需要一段时间来消化它。