代码之家  ›  专栏  ›  技术社区  ›  bluethundr

JQ拉拔结果不一致

  •  1
  • bluethundr  · 技术社区  · 6 年前

    如果我从一个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错误“不能在空值上迭代”。

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

    Original JSON

    如何使错误更详细,以便了解发生了什么?

    为什么向查询中添加name标签会显著减少结果的数量?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Jeff Mercado    6 年前

    在JSON中,并非所有实例都有一组 Tags 这样的错误。您必须处理它,或者用一个空数组替换它的位置 (.Tags // []) .但总的来说,我会这样写:

    .Reservations[].Instances[] | [ (.Tags // [] | from_entries.Name), .InstanceId ]
    
        2
  •  1
  •   peak    6 年前

    如何使错误更详细,以便了解发生了什么?

    你可以使用 debug .

    为什么向查询中添加name标签会显著减少结果的数量?

    因为您的JQ程序与您的期望不符;特别是,您忽略了当.tags的计算结果为空时会发生什么。要了解不匹配,请考虑:

    $ 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  ]