使用jq实现json的多数组级呈现
以下是ec2描述实例的all-ec2-instance.json输出:使用jq实现json的多数组级呈现,json,bash,amazon-ec2,jq,Json,Bash,Amazon Ec2,Jq,以下是ec2描述实例的all-ec2-instance.json输出: { "Reservations": [ { "OwnerId": "", "ReservationId": "", "Groups": [], "Instances": [ { "InstanceId": "i-11111111",
{
"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"
}
]
}
]
}
]
}
这是前面给出的答案的进一步问题。现在,我可以使用以下语法来获取实例标记值以及EBS卷ID:
cat all-ec2-instance.json |jq -r '.Reservations[] | .Instances[] | .Tags[].Value +" "+ .BlockDeviceMappings[].Ebs.VolumeId '
但是,如果我想从数组BlockDeviceMappings中获取另一个值,我将得到错误的结果,这意味着我无法正确显示不同级别数组的值,例如,标记值和卷ID和设备名称,我仍然会得到冗余的输出。我试过:
cat all-ec2-instance.json |jq -c -r '.Reservations[] | .Instances[] | .Tags[].Value +" "+ .BlockDeviceMappings[].Ebs.VolumeId +" "+ .BlockDeviceMappings[].DeviceName '
我会得到16个错误的结果,假设只有6个。如果只取同一级别数组中的VolumeId和DeviceName块设备应用程序,我们可以:
cat all-ec2-instance.json |jq -c -r '.Reservations[] | .Instances[] | .BlockDeviceMappings[] |.Ebs.VolumeId +" "+ .DeviceName '
在jq
中,如何存储前一级数组的值并将其分配给后一级数组循环?我尝试使用变量和其他jq函数,但没有成功:(
以下是所需的输出(逗号或任何其他分隔符都可以):
正如我在回答您的原始帖子时提到的,您可以直接从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命令中
首先,您可以重写第一个查询
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行是的,我意识到了。但我想知道如何用bash的方式解决这个问题,因为我将来还需要处理其他json文件。不过,我们也非常感谢您的输入!CLI使用的查询语言也有一个命令行工具,
jp
@JordonPhillips我想OP的意思是他会的希望使用JSon文件,该文件可能来自AWS CLI或其他版本,但不限于AWS CLI。它是一个开放规范,使用多种编程语言(ruby、php、python、javascript、java、lua、rust等)实现它有一个可以像jq
一样使用的工具。因此,即使您担心在aws cli之外使用查询,jmespath仍然是一个更好的选择。感谢@JordonPhillips,我知道它是jmespath,但我不知道命令行工具。如果您的问题包括您输入的查询的所需输出,那么它将非常有用端到端构造——这将使确定给定答案是否正确变得容易,并减少对当前用于构造该查询的特定机制的不适当关注(通常,这表示。这很有效!但是我在jq手册中找不到括号的用法,因此我永远不知道我们可以使用它来创建另一个数组的隔离循环。在jq手册中我可以在哪里找到括号的用法(以及如何创建隔离循环)?我正在使用这本手册:这取决于你想做什么,但由于你想连接字符串,你需要paranthes(像数学方法),你可以在完整的手册中查看,有一些例子使用paranthes,但它们没有专门的章节来说明它们的用法
"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"