jq - 如何 select 基于 'whitelist' 的 属性 值的对象
jq - How to select objects based on a 'whitelist' of property values
因为一个例子胜过一千个字,假设我有以下 JSON 流:
{"a": 0, "b": 1}
{"a": 2, "b": 2}
{"a": 7, "b": null}
{"a": 3, "b": 7}
如何保留 .b
属性 是 [1, 7]
之一的所有对象(实际上列表要长得多所以我不想做 select(.b == 1 or .b == 7)
).我正在寻找这样的东西:select(.b in [1, 7])
,但我在手册页中找不到我要找的东西。
可以使用模式 select($value == $collection[])
实现 $value in $collection
。一个更有效的替代方法是 select(any($value == $collection[]; .))
所以你的过滤器应该是这样的:
[1, 7] as $whitelist | select(any(.b == $whitelist[]; .))
将数组放在变量中有其好处,因为它可以让您使用参数轻松更改白名单。
$ jq --argjson whitelist '[2, 7]' 'select(any(.b == $whitelist[]; .))'
以下使用 index/1 的方法类似于最初寻求的方法 (".b in [1, 7]"),并且可能比在 select
中使用 .[] 快得多如果白名单很大。
如果你的jq支持--argjson:
jq --argjson w '[1,7]' '. as $in | select($w | index($in.b))'
否则:
jq --arg w '[1,7]' '. as $in | ($w|fromjson) as $w | select($w | index($in.b))'
或:
jq '. as $in | select([1, 7] | index($in.b))'
更新
2017 年 1 月 30 日,添加了名为 IN
的内置函数,用于高效测试流中是否包含 JSON 实体。它还可以用于有效地测试数组中的成员资格。例如,上面使用 --argjson 的调用可以简化为:
jq --argjson w '[1,7]' 'select( .b | IN($w[]) )'
如果你的jq没有IN/1
,那么只要你的jq有first/1
,你就可以使用这个等价的定义:
def IN(s): . as $in | first(if (s == $in) then true else empty end) // false;
因为一个例子胜过一千个字,假设我有以下 JSON 流:
{"a": 0, "b": 1}
{"a": 2, "b": 2}
{"a": 7, "b": null}
{"a": 3, "b": 7}
如何保留 .b
属性 是 [1, 7]
之一的所有对象(实际上列表要长得多所以我不想做 select(.b == 1 or .b == 7)
).我正在寻找这样的东西:select(.b in [1, 7])
,但我在手册页中找不到我要找的东西。
可以使用模式 select($value == $collection[])
实现 $value in $collection
。一个更有效的替代方法是 select(any($value == $collection[]; .))
所以你的过滤器应该是这样的:
[1, 7] as $whitelist | select(any(.b == $whitelist[]; .))
将数组放在变量中有其好处,因为它可以让您使用参数轻松更改白名单。
$ jq --argjson whitelist '[2, 7]' 'select(any(.b == $whitelist[]; .))'
以下使用 index/1 的方法类似于最初寻求的方法 (".b in [1, 7]"),并且可能比在 select
中使用 .[] 快得多如果白名单很大。
如果你的jq支持--argjson:
jq --argjson w '[1,7]' '. as $in | select($w | index($in.b))'
否则:
jq --arg w '[1,7]' '. as $in | ($w|fromjson) as $w | select($w | index($in.b))'
或:
jq '. as $in | select([1, 7] | index($in.b))'
更新
2017 年 1 月 30 日,添加了名为 IN
的内置函数,用于高效测试流中是否包含 JSON 实体。它还可以用于有效地测试数组中的成员资格。例如,上面使用 --argjson 的调用可以简化为:
jq --argjson w '[1,7]' 'select( .b | IN($w[]) )'
如果你的jq没有IN/1
,那么只要你的jq有first/1
,你就可以使用这个等价的定义:
def IN(s): . as $in | first(if (s == $in) then true else empty end) // false;