【问题标题】:How to pass an array to jq to filter results如何将数组传递给 jq 以过滤结果
【发布时间】:2021-07-05 11:59:54
【问题描述】:

我正在使用curljq 从 Github API 获取 PR 批准列表,以便在满足条件时在每个 PR 中添加标签。我有几个条件:

  • 批准数量必须至少为 2 并且
  • 我提供的列表中必须有一个批准人。

事实上,一切都运行良好,但我想美化我的代码,例如将列表作为参数传递,而不是在代码中硬编码。我在下面尝试过,但由于以下原因无法正常工作:

jq: 错误(at :1):无法迭代字符串(“joedoe”)

response=$(curl \
  -H "Accept: application/vnd.github.v3+json" \
  --request GET \
  --url https://api.github.com/repos/my-organization/my-repo/pulls/my-pr-number/reviews \
  --header "Authorization: token ***" \
  --header "Content-Type: application/json")

requiredViewers=("joedoe", "johnsmith", "johnstiles")

echo $response | jq --arg items $requiredViewers '( map( select( .state=="APPROVED" ) ) | 
                                                    map( { user: .user.login, state: .state, submitted_at: .submitted_at } ) | 
                                                    unique_by( .user ) | 
                                                    sort_by( .submitted_at ) | 
                                                    reverse ) | 
                                                    any( .[].user; . | 
                                                    IN ( $items[] --> this is not working ) ) and 
                                                    length>=2'

我查看了关于 SO 的类似帖子,但不幸的是无法使其正常工作。我的问题是,如何将列表作为参数传递并使其像硬编码一样工作?

【问题讨论】:

    标签: arrays shell curl environment-variables jq


    【解决方案1】:

    实现目标的最简单方法是将requiredViewers 定义为JSON 数组,并使用--argjson 而不是--arg 传递它(假设您的jq 版本支持--argjson):

    requiredViewers='["joedoe", "johnsmith", "johnstiles"]'
    
    echo "$response" |
      jq --argjson items "$requiredViewers" '
        ( map( select( .state=="APPROVED" ) ) 
          | map( { user: .user.login, state, submitted_at } )
          | unique_by( .user ) 
          | sort_by( .submitted_at )
          | reverse )
        | any( .[].user; 
               IN ( $items[] ) ) and length>=2
    '
    

    如果你的jq不支持--argjson

    如果您无法升级 jq,那么一种可能性是使用 --arg 将 JSON 数组作为字符串传递,然后使用 fromjson 将其转换为 JSON 数组。

    注意事项

    1. 前导 '. |'在诸如 '. | IN(...)' 应省略。
    2. 不要忘记引用您的 shell 变量。
    3. jq表达式{foo: .foo}可以简写为{foo}
    4. 您的 jq 程序的某些方面似乎没有多大意义,但在没有明确要求和示例 JSON 的情况下,我将重点放在主要问题上。
    5. 我建议采用不需要太多右缩进的样式; “左边的管道”风格适合我:-)

    【讨论】:

    • 伙计,你拯救了我的一天,我真的很感激!您不仅回答了这个问题,还提出了很大的改进。抱歉,我是jq 的新手,我想了解更多关于第 4 点的信息。如何简化此逻辑?我假设你在这个脚本中明白了我的意思:)
    • Re: (4) -- 在你的程序中对sort_byreverse 的调用对我来说没有意义。如果您希望管道中的最后一个过滤器是 select(any(...) and length>=2),那么在第二次选择之后进行排序会更有效......
    • 我明白了。感谢您的提醒,我会尝试一下!
    猜你喜欢
    • 2016-04-17
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多