JQ:Select 当属性值存在于 bash 数组中时

JQ: Select when attribute value exists in a bash array

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

selected_subnets="valueA valueB"

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

testmatch fn 仅适用于 v1.5。

这有点棘手,但可以用 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 的拆分是内联完成的之外,这基本上以相同的方式工作。

您可以使用 --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"
  }
]