json 多数组级渲染与 jq

Multiple array level of json rendering with jq

这是 ec2-describe-instances 的 all-ec2-instance.json 输出:

{
    "Reservations": [
        {
            "OwnerId": "",
            "ReservationId": "",
            "Groups": [],
            "Instances": [
                {

                    "InstanceId": "i-11111111",
                    "Hypervisor": "xen",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/sda1",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-11111111",
                                "AttachTime": "2016-04-19T15:53:53.000Z"
                            }
                        },
                        {
                            "DeviceName": "/dev/sdf",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-22222222",
                                "AttachTime": "2016-05-25T08:22:33.000Z"
                            }
                        },
                        {
                            "DeviceName": "/dev/sdg",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-33333333",
                                "AttachTime": "2016-02-28T04:22:07.000Z"
                            }
                        }
                    ],
                     "Tags": [
                        {
                            "Value": "ec2-test1",
                            "Key": "Name"
                        }
                    ]
                }
            ]
        },
        {
            "OwnerId": "",
            "ReservationId": "",
            "Groups": [],
            "Instances": [
                {

                    "InstanceId": "i-22222222",
                    "Hypervisor": "xen",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/sda1",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-44444444",
                                "AttachTime": "2016-05-19T15:53:53.000Z"
                            }
                        },
                        {
                            "DeviceName": "/dev/sdf",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-55555555",
                                "AttachTime": "2015-08-25T08:22:33.000Z"
                            }
                        },
                        {
                            "DeviceName": "/dev/sdg",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-66666666",
                                "AttachTime": "2016-07-28T04:22:07.000Z"
                            }
                        }
                    ],
                     "Tags": [
                        {
                            "Value": "ec2-test2",
                            "Key": "Name"
                        }
                    ]
                }
            ]
        }
    ]
}

这是先前给出的答案 的进一步问题。我现在可以使用以下语法来获取实例 Tag value 以及 EBS volumeid:

cat all-ec2-instance.json |jq -r '.Reservations[] | .Instances[] |  .Tags[].Value  +" "+ .BlockDeviceMappings[].Ebs.VolumeId '

但是如果我想从数组BlockDeviceMappings中获取另一个值,我会得到错误的结果,这意味着我无法正确显示不同级别数组的值,例如,Tag value and VolumeId and DeviceName,我仍然会得到多余的输出。我试过了:

cat all-ec2-instance.json |jq -c -r '.Reservations[] | .Instances[] |  .Tags[].Value +" "+ .BlockDeviceMappings[].Ebs.VolumeId +" "+ .BlockDeviceMappings[].DeviceName '

我会得到 16 个错误的结果,假设只有 6 个。如果只取 VolumeIdDeviceName 它们在同一级别数组 BlockDeviceMappings 我们可以这样做:

cat all-ec2-instance.json |jq -c -r '.Reservations[] | .Instances[] |  .BlockDeviceMappings[] |.Ebs.VolumeId +" "+ .DeviceName '

jq中,我们如何存储上一层数组的值,并赋值给后面的数组循环?我尝试使用变量和其他 jq 函数但没有成功:(

这是所需的输出(逗号或任何其他分隔符都可以):

ec2-test1,vol-11111111,/dev/sda1
ec2-test1,vol-22222222,/dev/sdf
ec2-test1,vol-33333333,/dev/sdg
ec2-test2,vol-44444444,/dev/sda1
ec2-test2,vol-55555555,/dev/sdf
ec2-test2,vol-66666666,/dev/sdg

正如我在对您的原始 post 的回答中提到的,您可以直接从 AWS CLI 完成大部分工作

获取实例标签值以及 EBS volumeid:

aws ec2 describe-instances --query "Reservations[].Instances[].[BlockDeviceMappings[].Ebs.VolumeId, Tags[].Value]"

如果要扩展获取DeviceName字段

aws ec2 describe-instances --query "Reservations[].Instances[].[BlockDeviceMappings[].[DeviceName, Ebs.VolumeId], Tags[].Value]"

如果您想保留文本(就像您 运行 来自 jq 的原始数据一样),您可以将 --output text 标志添加到 CLI 命令

我会再做一个与jq一起工作的答案

首先你可以重写第一个查询

cat all-ec2-instance.json \
| jq -r '.Reservations[].Instances[] | .Tags[].Value +" "+ .BlockDeviceMappings[].Ebs.VolumeId'

然后,如果您想从 Json 添加附加值,例如 `DeviceName``

cat all-ec2-instance.json \
| jq -r '.Reservations[].Instances[] | .Tags[].Value +" "+(.BlockDeviceMappings[] | .Ebs.VolumeId +" "+ .DeviceName)'

你得到以下内容

"ec2-test1 vol-11111111 /dev/sda1"
"ec2-test1 vol-22222222 /dev/sdf"
"ec2-test1 vol-33333333 /dev/sdg"
"ec2-test2 vol-44444444 /dev/sda1"
"ec2-test2 vol-55555555 /dev/sdf"
"ec2-test2 vol-66666666 /dev/sdg"

你期望的是哪 6 行