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 个。如果只取 VolumeId 和 DeviceName 它们在同一级别数组 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 行
这是 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"
}
]
}
]
}
]
}
这是先前给出的答案
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 个。如果只取 VolumeId 和 DeviceName 它们在同一级别数组 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 行