【问题标题】:Select entries based on multiple values in jq根据jq中的多个值选择条目
【发布时间】:2017-11-26 00:41:08
【问题描述】:

我正在与 JQ 合作,到目前为止我非常喜欢它。不过,我遇到了一个问题,我还没有找到其他任何地方的解决方案,我想看看社区是否有办法做到这一点。

假设我们有一个如下所示的 JSON 文件:

{"author": "Gary", "text": "Blah"}
{"author": "Larry", "text": "More Blah"}
{"author": "Jerry", "text": "Yet more Blah"}
{"author": "Barry", "text": "Even more Blah"}
{"author": "Teri", "text": "Text on text on text"}
{"author": "Bob", "text": "Another thing to say"}

现在,我们要选择author 的值等于“Gary”或“Larry”的行,但没有其他情况。实际上,我要检查数千个名称,因此仅说明直接或条件(例如cat blah.json | jq -r 'select(.author == "Gary" or .author == "Larry")')是不够的。我正在尝试通过 inside 函数执行此操作,但得到一个错误对话框:

cat blah.json | jq -r 'select(.author | inside(["Gary", "Larry"]))'
jq: error (at <stdin>:1): array (["Gary","La...) and string ("Gary") cannot have their containment checked

做这样的事情最好的方法是什么?

【问题讨论】:

  • 你不需要inside函数,你可以得到select(.author == ("Gary", "Larry"))这样的条目

标签: json jq whitelist


【解决方案1】:

IRC 用户 gnomon 在jq channel 上回答如下:

jq 'select([.author] | inside(["Larry", "Garry", "Jerry"]))'

正如用户所说,这种方法背后的直觉是:“从字面上看,您的想法是,仅将 .author 包装为 [.author] 以将其强制为单项数组,因此 inside() 将起作用。”这个答案产生了过滤列表中提供的一系列名称作为原始问题所需的预期结果。

【讨论】:

  • 这将执行子字符串搜索。 "Lar""erry""J" 将全部匹配。
【解决方案2】:

您可以像使用集合一样使用对象来测试成员资格。对数组进行操作的方法效率低下,尤其是在数组可能很大的情况下。

您可以在读取输入之前建立一组值,然后使用该组过滤您的输入。

$ jq -n --argjson names '["Larry","Garry","Jerry"]' '
(reduce $names[] as $name ({}; .[$name] = true)) as $set
    | inputs | select($set[.author])
' blah.json

【讨论】:

    【解决方案3】:

    insidecontains 有点奇怪。以下是一些更直接的解决方案:

    索引/1

    select( .author as $a | ["Gary", "Larry"] | index($a) )
    

    任何/2

    ["Gary", "Larry"] as $whitelist
    | select( .author as $a | any( $whitelist[]; . == $a) )
    

    使用字典

    如果性能是一个问题,并且如果“作者”始终是一个字符串,那么应该考虑采用 @JeffMercado 建议的解决方案。这是一个变体(与 -n 命令行选项一起使用):

    ["Gary", "Larry"] as $whitelist
    | ($whitelist | map( {(.): true} ) | add) as $dictionary
    | inputs
    | select($dictionary[.author])
    

    【讨论】:

      猜你喜欢
      • 2016-01-08
      • 1970-01-01
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-04
      相关资源
      最近更新 更多