JQ拉结果不一致

时间:2018-11-30 19:12:08

标签: iteration jq

如果我通过aws命令对我的json数据运行此非常直接的查询,则我会得到一个帐户中有多少个AWS服务器实例的正确结果:

aws ec2 describe-instances | jq -r '.Reservations[].Instances[].InstanceId'

产生一个47个实例ID的列表,这些ID与我在帐户中拥有的服务器实例的数量相对应。例如:

i-01adbf1408ef1a333
i-0f92d078ce975c138
i-0e4e117c44b17b417
and on up to 47 instances

下一个查询仍然会产生正确数量的结果:

aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | [( .InstanceId ) ]'

但是,如果我添加一个包含服务器名称标签的查询,则报告的服务器实例数量将大大减少:

aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | [( (.Tags[]|select(.Key=="Name")|.Value), .InstanceId ) ]'

这是该命令的输出:

"i-08d3c05eed1316c9d"
"USAMZLAB10003","i-79eebb29"
"EOMLABAMZ1306","i-dbc98af4"
"USAMZLAB10002","i-d1dc1d83"
"i-0366c9bf18d27eb96"
"i-04d061334bc2f2d6b"
"USAMZLAB10007","i-f7a680a7"
"i-090e84eff4fece2b3"
"EOMLABAMZ1303","i-7cc98a53"
"EOMLABCSE713","i-08233926"
"i-0705eb3039cd56e04"
jq: error (at <stdin>:5013): Cannot iterate over null (null)

由于某种原因,查询报告仅存在11个aws服务器实例(应为47个)。它确实报告有带或不带名称标签的服务器。但是它没有报告正确的服务器数量。

它还会产生jq错误“无法遍历null”。

我已将原始JSON放入此粘贴中:

Original JSON

如何使错误更详细,以便找出发生了什么情况?

为什么在查询中添加名称标签会大大减少结果数量?

2 个答案:

答案 0 :(得分:2)

在您的json中,并非所有实例都有一组Tags,因此会出现错误。您将不得不处理它或用(.Tags // [])替换一个空数组。但总的来说,我会这样写:

.Reservations[].Instances[] | [ (.Tags // [] | from_entries.Name), .InstanceId ]

答案 1 :(得分:1)

  

如何使错误更详细,以便找出发生了什么情况?

您可以使用debug

  

为什么在查询中添加名称标签会大大减少结果数量?

因为您的jq程序与您的期望不一致;特别是,您忽略了.Tags评估为null时会发生的情况。要了解不匹配,请考虑:

$ jq -n '{} | .Tags[]|select(.Key=="Name")|.Value'

另一个问题是处理空数组。您可能希望按照以下建议的方式处理空数组的情况:

$ jq -n '{Tags: []} | (.Tags[] | select(.Key=="Name")|.Value) // null'
$ null

一种解决方案

如果您希望null在没有标签的情况下显示:

.Reservations[].Instances[]
| [ ((.Tags // [])[] | select(.Key=="Name") | .Value) // null,
    .InstanceId  ] 

给出您的输入,输出的前两行将是:

[null,"i-08d3c05eed1316c9d"]
["USAMZLAB10003","i-79eebb29"]

使用try

的变体
.Reservations[].Instances[]
| [ try (.Tags[] | select(.Key=="Name")|.Value) // null,
    .InstanceId  ]