我有一个像这样的行的文件:
{"items":["blue","green"]}
{"items":["yellow","green"]}
{"items":["blue","pink"]}
Run Code Online (Sandbox Code Playgroud)
如何使用jq选择并仅显示其"items"数组中具有"blue"的JSON值?
所以输出将是:
{"items":["blue","green"]}
{"items":["blue","pink"]}
Run Code Online (Sandbox Code Playgroud)
2017 年 1 月 30 日,IN添加了一个名为的内置函数,用于高效测试流中是否包含 JSON 实体。它还可用于有效测试数组中的成员资格。在本案中,相关用法为:
select( .items as $items | "blue" | IN($items[]) )
Run Code Online (Sandbox Code Playgroud)
如果您的 jq 没有IN/1,那么只要您的 jq 有first/1,您就可以使用以下等效定义:
def IN(s): . as $in | first(if (s == $in) then true else empty end) // false;
Run Code Online (Sandbox Code Playgroud)
any/0在这里使用效率相对较低,例如与使用相比any/1:
select( any( .items[]; . == "blue" ))
Run Code Online (Sandbox Code Playgroud)
(在实践中,index/1通常足够快,但它目前的实现(jq 1.5 和至少到 2017 年 7 月的版本)是次优的。)
虽然您所拥有的肯定有效,但使用contains. 我会避免这种使用,因为它会导致混乱。 index("blue")是0并且人们不会认为这是一个真实值,并可能期望它被排除在结果之外。
考虑改用这个过滤器:
select(.items | contains(["blue"]))
Run Code Online (Sandbox Code Playgroud)
这有一个额外的好处,如果您希望通过简单地向数组添加多个匹配项来获得多个匹配项,它将起作用。
正如 Will 在评论中指出的那样,这并不完全正确。contains在这里使用子字符串匹配(递归使用)比较字符串。
回想起来,contains并没有像我想象的那样成功。使用index作品,但我个人不会使用它。通过查找我觉得不对的索引来确定一个项目是否在集合中是有一些事情的。使用contains对我来说更有意义,但根据这些信息,在这种情况下它并不理想。
这是一个应该可以正常工作的替代方法:
select([.items[] == "blue"] | any)
Run Code Online (Sandbox Code Playgroud)
或者,如果您希望能够匹配更多值,则采用更具可扩展性的方式:
select(.items as $values | ["blue", "yellow"] | map([$values[] == .] | any) | all)
Run Code Online (Sandbox Code Playgroud)
小智 5
我需要对对象的相同情况使用“正则表达式”。(当然,在另一种情况下)。我编写代码是因为我在这些页面中没有找到满足我需要的解决方案。这对某人来说可能很有用。
例如,要使用正则表达式匹配蓝色:
jq 'select(.items[]|test("bl.*"))' yourfile.json
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17523 次 |
| 最近记录: |