jq-将嵌套JSON提取到多个数组中
我在这篇文章的底部有一些经过编辑的JSON,这是在AWS中运行ec2描述实例的结果。示例JSON有2个数组,但是这个数组可能更大。我以前使用过jq,但是我在提取JSON中深度嵌套的值时遇到了困难。我特别感兴趣的是: InstanceId[保留:[实例:[InstanceId: DeviceName[保留:[实例:[块设备应用:[设备名称: VolumeId[保留:[实例:[块设备应用:[Ebs:{VolumeId: TAG1值/键 TAG2值/键 总而言之,我需要一个可以迭代的JSON数组,该数组将为我提供一个InstanceID、该实例上的标记和一个卷。您会注意到每个实例都连接了3个卷,可能更多,也可能更少。我希望能够单独迭代每个卷。我希望最终的结果如下所示:jq-将嵌套JSON提取到多个数组中,json,jq,Json,Jq,我在这篇文章的底部有一些经过编辑的JSON,这是在AWS中运行ec2描述实例的结果。示例JSON有2个数组,但是这个数组可能更大。我以前使用过jq,但是我在提取JSON中深度嵌套的值时遇到了困难。我特别感兴趣的是: InstanceId[保留:[实例:[InstanceId: DeviceName[保留:[实例:[块设备应用:[设备名称: VolumeId[保留:[实例:[块设备应用:[Ebs:{VolumeId: TAG1值/键 TAG2值/键 总而言之,我需要一个可以迭代的JSON数组,该数
[
{
"InstanceId": "i-11111111",
"DeviceName": "/dev/sda1",
"VolumeId": "vol-1111111a",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
},
{
"InstanceId": "i-11111111",
"DeviceName": "xvdf",
"VolumeId": "vol-1111111b",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
},
{
"InstanceId": "i-11111111",
"DeviceName": "xvdg",
"VolumeId": "vol-1111111c",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
},
{
"InstanceId": "i-22222222",
"DeviceName": "/dev/sda1",
"VolumeId": "vol-2222222a",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
},
{
"InstanceId": "i-22222222",
"DeviceName": "/dev/sdb",
"VolumeId": "vol-2222222b",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
},
{
"InstanceId": "i-22222222",
"DeviceName": "/dev/sdc",
"VolumeId": "vol-2222222c",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
}
]
这类似于我发布的另一个问题。我尝试了这么多不同的组合,但都无法实现。非常感谢您的帮助
以下是JSON:
{
"Reservations": [
{
"OwnerId": "xx",
"ReservationId": "xx",
"Groups": [],
"Instances": [
{
"Monitoring": {
"State": "xx"
},
"PublicDnsName": "",
"Platform": "xx",
"State": {
"Code": xx,
"Name": "xx"
},
"EbsOptimized": xx,
"LaunchTime": "xx",
"PrivateIpAddress": "xx",
"ProductCodes": [],
"VpcId": "xx",
"StateTransitionReason": "",
"InstanceId": "i-11111111",
"ImageId": "xx",
"PrivateDnsName": "xx",
"KeyName": "xx",
"SecurityGroups": [
{
"GroupName": "xx",
"GroupId": "xx"
},
{
"GroupName": "xx",
"GroupId": "xx"
}
],
"ClientToken": "xx",
"SubnetId": "xx",
"InstanceType": "xx",
"NetworkInterfaces": [
{
"Status": "xx",
"MacAddress": "xx",
"SourceDestCheck": xx,
"VpcId": "xx",
"Description": "xx",
"NetworkInterfaceId": "xx",
"PrivateIpAddresses": [
{
"PrivateDnsName": "xx",
"Primary": xx,
"PrivateIpAddress": "xx"
}
],
"PrivateDnsName": "xx",
"Attachment": {
"Status": "xx",
"DeviceIndex": xx,
"DeleteOnTermination": xx,
"AttachmentId": "xx",
"AttachTime": "xx"
},
"Groups": [
{
"GroupName": "xx",
"GroupId": "xx"
},
{
"GroupName": "xx",
"GroupId": "xx"
}
],
"SubnetId": "xx",
"OwnerId": "xx",
"PrivateIpAddress": "xx"
}
],
"SourceDestCheck": xx,
"Placement": {
"Tenancy": "xx",
"GroupName": "xx",
"AvailabilityZone": "xx"
},
"Hypervisor": "xx",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda1",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": xx,
"VolumeId": "vol-1111111a",
"AttachTime": "xx"
}
},
{
"DeviceName": "xvdf",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": xx,
"VolumeId": "vol-1111111b",
"AttachTime": "xx"
}
},
{
"DeviceName": "xvdg",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": xx,
"VolumeId": "vol-11111111c",
"AttachTime": "xx"
}
}
],
"Architecture": "xx",
"RootDeviceType": "xx",
"RootDeviceName": "xx",
"VirtualizationType": "hvm",
"Tags": [
{
"Value": "TAG1",
"Key": "VALUE1"
},
{
"Value": "TAG2",
"Key": "VALUE2"
},
{
"Value": "TAG3",
"Key": "VALUE3"
},
{
"Value": "TAG4",
"Key": "VALUE4"
},
{
"Value": "TAG5",
"Key": "VALUE5"
},
{
"Value": "TAG6",
"Key": "Value6"
}
],
"AmiLaunchIndex": xx
}
]
},
{
"OwnerId": "xx",
"ReservationId": "xx",
"Groups": [],
"Instances": [
{
"Monitoring": {
"State": "xx"
},
"PublicDnsName": "",
"Platform": "xx",
"State": {
"Code": xx,
"Name": "xx"
},
"EbsOptimized": xx,
"LaunchTime": "xx",
"PrivateIpAddress": "xx",
"ProductCodes": [],
"VpcId": "xx",
"StateTransitionReason": "",
"InstanceId": "i-22222222",
"ImageId": "xx",
"PrivateDnsName": "xx",
"KeyName": "xx",
"SecurityGroups": [
{
"GroupName": "xx",
"GroupId": "xx"
},
{
"GroupName": "xx",
"GroupId": "xx"
}
],
"ClientToken": "xx",
"SubnetId": "xx",
"InstanceType": "xx",
"NetworkInterfaces": [
{
"Status": "xx",
"MacAddress": "xx",
"SourceDestCheck": xx,
"VpcId": "xx",
"Description": "xx",
"NetworkInterfaceId": "xx",
"PrivateIpAddresses": [
{
"PrivateDnsName": "xx",
"Primary": xx,
"PrivateIpAddress": "xx"
}
],
"PrivateDnsName": "xx",
"Attachment": {
"Status": "xx",
"DeviceIndex": xx,
"DeleteOnTermination": xx,
"AttachmentId": "xx",
"AttachTime": "xx"
},
"Groups": [
{
"GroupName": "xx",
"GroupId": "xx"
},
{
"GroupName": "xx",
"GroupId": "xx"
}
],
"SubnetId": "xx",
"OwnerId": "xx",
"PrivateIpAddress": "xx"
}
],
"SourceDestCheck": xx,
"Placement": {
"Tenancy": "xx",
"GroupName": "xx",
"AvailabilityZone": "xx"
},
"Hypervisor": "xx",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda1",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": xx,
"VolumeId": "vol-2222222a",
"AttachTime": "xx"
}
},
{
"DeviceName": "/dev/sdb",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": xx,
"VolumeId": "vol-2222222b",
"AttachTime": "xx"
}
},
{
"DeviceName": "/dev/sdc",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": xx,
"VolumeId": "vol-2222222c",
"AttachTime": "xx"
}
}
],
"Architecture": "xx",
"RootDeviceType": "xx",
"RootDeviceName": "xx",
"VirtualizationType": "hvm",
"Tags": [
{
"Value": "TAG1",
"Key": "VALUE1"
},
{
"Value": "TAG2",
"Key": "VALUE2"
},
{
"Value": "TAG3",
"Key": "VALUE3"
},
{
"Value": "TAG4",
"Key": "VALUE4"
},
{
"Value": "TAG5",
"Key": "VALUE5"
},
{
"Value": "TAG6",
"Key": "Value6"
}
],
"AmiLaunchIndex": xx
}
]
}
]
编辑:我尝试过的一个例子是,为了简单起见,不尝试获取标签:
jq -r '.Reservations.Instances | map(({ InstanceId } + (.BlockDeviceMappings | add) + (.BlockDeviceMappings.Ebs | Add))| { InstanceId, DeviceName, VolumeId })' <(echo "$json_array_windows")
jq: error: Add/0 is not defined at <top-level>, line 1:
.Reservations.Instances | map(({ InstanceId } + (.BlockDeviceMappings | add) + (.BlockDeviceMappings.Ebs | Add))| { InstanceId, DeviceName, VolumeId })
jq: 1 compile error
下面的jq过滤器根据请求生成JSON对象流。 如果您确实需要一个JSON数组,那么只需将整个表达式包装在方括号中即可
.Reservations[] | .Instances[]
| { InstanceId }
+ (.BlockDeviceMappings[]
| { DeviceName,
"VolumeId": .Ebs.VolumeId } )
+ (.Tags
| { "TAG1": ( map( select(.Value == "TAG1"))[] | .Key),
"TAG2": ( map( select(.Value == "TAG2"))[] | .Key) } )
以下是更正输入JSON后的输出:
{
"InstanceId": "i-11111111",
"DeviceName": "/dev/sda1",
"VolumeId": "vol-1111111a",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
}
{
"InstanceId": "i-11111111",
"DeviceName": "xvdf",
"VolumeId": "vol-1111111b",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
}
{
"InstanceId": "i-11111111",
"DeviceName": "xvdg",
"VolumeId": "vol-11111111c",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
}
{
"InstanceId": "i-22222222",
"DeviceName": "/dev/sda1",
"VolumeId": "vol-2222222a",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
}
{
"InstanceId": "i-22222222",
"DeviceName": "/dev/sdb",
"VolumeId": "vol-2222222b",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
}
{
"InstanceId": "i-22222222",
"DeviceName": "/dev/sdc",
"VolumeId": "vol-2222222c",
"TAG1": "VALUE1",
"TAG2": "VALUE2"
}
非常感谢!但我注意到所有DeviceName都是“/dev/sda1”,这似乎有误。你说我希望能够逐个迭代每个DeviceName。正如我所指出的,我只显示了前三个JSON对象。很抱歉没有正确地使用这些对象。我确实需要将“DeviceName”正确映射到“VolumeId”。你认为呢墨迹这是可能的?我想你会发现修改后的答案符合你的期望。有没有办法得到一个没有找到的标签的值,只是说“null”,而不是什么都不显示?很高兴打开另一个线程