首页 > 解决方案 > jq,基于“aws describe-instance”连接来自不同级别的同一子对象的两个值

问题描述

我知道as声明,但不知道如何使用它,我想我应该这样做:

jq '
    Reservations | .[].Instances as root
    $root.Tags | .[] | select(.Key=="Name") | .Value , 
    $root.BlockDeviceMappings | $root.[].Ebs.VolumeId
' file.json

目标是遍历每个实例并映射Tags.Value(select on .Key=="Name") 和.Ebs.VolumeId.

输入文件示例:

{
    "Reservations": [
        {
            "Instances": [
               {
                     "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/xvda",
                            "Ebs": {
                                "DeleteOnTermination": true,
                                "VolumeId": "vol-fffffffffffff"
                             }
                          }
                        ],
                        "Tags": [
                            {
                                "Value": "FOO - DEV - BAR - instance-name",
                                "Key": "Name"
                            }
                    ]
                }
            ],
            "ReservationId": "r-xxxx"
        },
        {
              "Instances": [
                    "another same kind of sub-objects with different values like above repeated"
                ]
        }
    ]
}

最后一个子对象:

"Instances": [
     "another same kind of sub-objects with different values like above repeated"
 ]

Instances是假的,它是像第一个一样重复的子对象,具有不同的真实值

预期输出为:

FOO - DEV - BAR - instance-name:vol-fffffffffffff

标签: jsonamazon-web-servicesjq

解决方案


给定您的输入,您的 jq 程序的以下变体会产生所需的输出:

(.Reservations[].Instances[]) as $root
| ($root.Tags? | .[] | select(.Key=="Name") | .Value) + ":" 
  + ($root.BlockDeviceMappings? | .[].Ebs.VolumeId) 

实际上不需要引入$root变量——你也可以这样写:

(.Reservations[].Instances[])
| (.Tags? | .[] | select(.Key=="Name").Value) + ":" 
  + (.BlockDeviceMappings? | .[].Ebs.VolumeId) 

注意事项

指某东西的用途 ”?” 我怀疑以上是必需的,因为您的示例 JSON 是人为设计的。

另外,我不确定要求是什么,所以上面的内容可能不是你真正想要的。一旦您掌握了 jq 的语法,您可能希望更准确地捕捉您的需求。


推荐阅读