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