如何根据数组中的值选择JQ中的项目

时间:2014-09-03 17:05:21

标签: json jq

我有一个包含这样的行的文件:

{"items":["blue","green"]}
{"items":["yellow","green"]}
{"items":["blue","pink"]}

如何使用jq选择并仅显示具有" blue"的JSON值?在他们的"项目"阵列

所以输出结果为:

{"items":["blue","green"]}
{"items":["blue","pink"]}

4 个答案:

答案 0 :(得分:6)

找到答案

jq 'select(.items | index("blue"))'

答案 1 :(得分:4)

2017年1月30日,添加了一个名为IN的内置程序,用于有效地测试流中是否包含JSON实体。它还可用于有效地测试阵列中的成员资格。在本案中,相关用法是:

select( .items as $items | "blue" | IN($items[]) )

如果你的jq没有IN/1,那么只要你的jq有first/1,你就可以使用这个等价的定义:

def IN(s): . as $in | first(if (s == $in) then true else empty end) // false;

任何/ 0

在这里使用any/0效率相对较低,例如与使用any/0

相比
select( any( .items[]; . == "blue" ))

(实际上,index/1通常足够快,但目前的实施(jq 1.5和至少2017年7月的版本)不是最理想的。)

答案 2 :(得分:3)

<击> 虽然您确实有效,但使用contains更为正确。我会避免使用它,因为它可能导致混淆。 index("blue")0,人们不会认为这是一个真正的价值,可能会将其排除在结果之外。

请考虑使用此过滤器:

select(.items | contains(["blue"]))

如果你想通过简单地向数组中添加更多项来获得具有多个匹配项的项,那么它具有额外的好处。

正如威尔在评论中指出的那样,这并不完全正确。字符串使用子串匹配进行比较(contains递归使用)。

回想起来,contains并没有像我想象的那样成功。使用index有效,但我个人不会使用它。通过查找对我来说错误的索引,可以确定某个项目是否在集合中。使用contains对我来说更有意义,但根据这些信息,在这种情况下它并不理想。


这是一个应该正常运作的替代方案:

select([.items[] == "blue"] | any)

如果您希望能够匹配更多值,可以采用更具伸缩性的方式:

select(.items as $values | ["blue", "yellow"] | map([$values[] == .] | any) | all)

答案 3 :(得分:1)

对于相同的对象情况,我需要使用“ regex”。 (当然,在另一种情况下)。我写代码是因为在这些页面中找不到适合我需要的解决方案。这对某人可能有用。

例如,使用正则表达式匹配蓝色:

jq 'select(.items[]|test("bl.*"))' yourfile.json

jqPlay