首页 > 解决方案 > 如何将数组传递给 jq 以过滤结果

问题描述

我正在从 Github API 获取 PR 批准列表,如果满足条件,则在每个 PR 中放置一个标签curljq我有几个条件,即;

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

jq:错误(在: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 的类似帖子,但不幸的是无法正常工作。我的问题是,如何将列表作为参数传递并使其像硬编码一样工作?

标签: arraysshellcurlenvironment-variablesjq

解决方案


实现目标的最简单方法是将其定义requiredViewers为 JSON 数组,并将其传递给 using--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,那么一种可能性是使用 将 JSON 数组作为字符串传递--arg,并使用fromjson将其转换为 JSON 数组。

笔记

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

推荐阅读