【问题标题】:JQ: Select when attribute value exists in a bash arrayJQ:当属性值存在于bash数组中时选择
【发布时间】:2015-03-19 10:30:55
【问题描述】:

我正在使用 jq 1.4。 当我的$selected_subnets(bash 变量)中存在 VPCZoneIdentifier 时,我尝试选择元素。

selected_subnets="valueA valueB"

input='{"elements":[
           {"name": "nameA", "VPCZoneIdentifier": "valueA"}, 
           {"name": "nameB", "VPCZoneIdentifier": "valueB"}, 
           {"name": "nameC", "VPCZoneIdentifier": "valueC"}
       ]}'

testmatch fn 仅适用于 v1.5。

【问题讨论】:

    标签: bash amazon-ec2 vpc jq


    【解决方案1】:

    这有点棘手,但可以使用reduce 完成。整个事情可能是这样的:

    selected_subnets_json=$(echo "\"$selected_subnets\"" | jq -c -M 'split(" ")')
    echo "$input" | jq -M '.elements = [.elements[] | select(.VPCZoneIdentifier as $id | '"$selected_subnets_json"' | reduce .[] as $v (false; . or $id == $v))]'
    

    第一部分从 shell 列表中创建一个 JSON 数组:

    $ echo "\"$selected_subnets\"" | jq -c -M 'split(" ")'
    ["valueA","valueB"]
    

    第二部分使用reduce 过滤器将.VPCZoneIdentifier 属性与该数组的所有元素进行比较。将selected_subnets_json 变量扩展到其中后,过滤器如下所示:

    .elements = [
      .elements[] |
        select(.VPCZoneIdentifier as $id |
               [ "valueA", "valueB" ] | reduce .[] as $v (false; . or $id == $v))
    ]
    

    也就是说,elements 属性会被其中符合选择标准的元素覆盖

    .VPCZoneIdentifier as $id | [ "valueA", "valueB" ] | reduce .[] as $v (false; . or $id == $v))
    

    其中第一部分将VPCZoneIdentifier 记住为$id(因为. 很快将意味着完全不同的东西),并且

    [ "valueA", "valueB" ] | reduce .[] as $v (false; . or $id == $v))
    

    是子网数组的或约。在这种情况下,它会扩展为 false or $id == "valueA" or $id == "valueB"

    如果你更喜欢一口气搞定,你可以写

    echo "$input" | jq -M '.elements = [.elements[] | select(.VPCZoneIdentifier as $id | ("'"$selected_subnets"'" | split(" ")) | reduce .[] as $v (false; . or $id == $v))]'
    

    除了$selected_subnets 的拆分是内联完成的之外,它的工作原理基本相同。

    【讨论】:

      【解决方案2】:

      您可以使用--arg 选项从命令行设置变量在您的查询中可用。然后,您可以使用 select 过滤器过滤掉元素。给定一个值数组,您可以执行"value in array" 测试,执行以下操作:

      value == (array[])
      

      因此您的过滤器将具有以下结构:

      .elements | map(
          select(
              .VPCZoneIdentifier == ($subnets | split(" ")[])
          )
      )
      

      把它和你的变量放在一起:

      $ echo $input | jq --arg subnets "$selected_subnets" '.elements | map(select(.VPCZoneIdentifier == ($subnets | split(" ")[])))'
      [
        {
          "name": "nameA",
          "VPCZoneIdentifier": "valueA"
        },
        {
          "name": "nameB",
          "VPCZoneIdentifier": "valueB"
        }
      ]
      

      【讨论】:

        猜你喜欢
        • 2019-07-04
        • 2016-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多