3

我正在使用 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"}
       ]}'

testmatchfn 仅在 v1.5 上可用。

4

2 回答 2

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))

其中第一部分记住VPCZoneIdentifieras $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是内联完成的。

于 2015-03-19T12:24:16.750 回答
4

--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"
  }
]
于 2015-03-20T01:42:09.917 回答