如何将数组传递给 jq 以过滤结果
How to pass an array to jq to filter results
我正在使用 curl
和 jq
从 Github API 获取 PR 批准列表,如果条件满足,我会在每个 PR 中放置一个标签。我有几个条件,即;
- 批准数必须至少为 2 并且
- 其中一个批准人必须在我提供的列表中。
事实上,一切都运行良好,但我想美化我的代码,例如将列表作为参数传递,而不是将其硬编码到代码中。我在下面尝试过,但由于以下原因无法正常工作:
jq: error (at :1): Cannot iterate over string ("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 上看过类似的帖子,但不幸的是无法正常工作。我的问题是如何将列表作为参数传递并使其像硬编码一样工作?
实现目标的最简单方法是将 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数组。
备注
- 龙头'。 |'在诸如 '. | IN(...)' 应省略。
- 不要忘记引用您的 shell 变量。
- jq表达式
{foo: .foo}
可以简写为{foo}
- 您的 jq 程序的某些方面似乎没有多大意义,但在没有明确要求和示例的情况下 JSON,我将重点放在主要问题上。
- 我建议采用不需要太多右缩进的样式; “左边的管道”风格适合我:-)
我正在使用 curl
和 jq
从 Github API 获取 PR 批准列表,如果条件满足,我会在每个 PR 中放置一个标签。我有几个条件,即;
- 批准数必须至少为 2 并且
- 其中一个批准人必须在我提供的列表中。
事实上,一切都运行良好,但我想美化我的代码,例如将列表作为参数传递,而不是将其硬编码到代码中。我在下面尝试过,但由于以下原因无法正常工作:
jq: error (at :1): Cannot iterate over string ("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 上看过类似的帖子,但不幸的是无法正常工作。我的问题是如何将列表作为参数传递并使其像硬编码一样工作?
实现目标的最简单方法是将 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数组。
备注
- 龙头'。 |'在诸如 '. | IN(...)' 应省略。
- 不要忘记引用您的 shell 变量。
- jq表达式
{foo: .foo}
可以简写为{foo}
- 您的 jq 程序的某些方面似乎没有多大意义,但在没有明确要求和示例的情况下 JSON,我将重点放在主要问题上。
- 我建议采用不需要太多右缩进的样式; “左边的管道”风格适合我:-)