【问题标题】:How to iterate a JSON array of objects with jq and grab multiple variables from each object in each loop如何使用 jq 迭代 JSON 对象数组并从每个循环中的每个对象中获取多个变量
【发布时间】:2021-06-17 02:56:18
【问题描述】:

我需要从 JSON 属性中获取变量。

JSON 数组看起来像这样(存储库标签的 GitHub API),我从 curl 请求中获得。

[
    {
        "name": "my-tag-name",
        "zipball_url": "https://api.github.com/repos/path-to-my-tag-name",
        "tarball_url": "https://api.github.com/repos/path-to-my-tag-name-tarball",
        "commit": {
            "sha": "commit-sha",
            "url": "https://api.github.com/repos/path-to-my-commit-sha"
        },
        "node_id": "node-id"
    },
    {
        "name": "another-tag-name",
        "zipball_url": "https://api.github.com/repos/path-to-my-tag-name",
        "tarball_url": "https://api.github.com/repos/path-to-my-tag-name-tarball",
        "commit": {
            "sha": "commit-sha",
            "url": "https://api.github.com/repos/path-to-my-commit-sha"
        },
        "node_id": "node-id"
    },
]

在我的实际 JSON 中,有 100 多个这样的对象。

当我循环其中的每一个时,我需要获取名称和提交 URL,然后在我到达下一个对象并重复之前对这两个变量执行更多操作。

我试过(有和没有-r)

tags=$(curl -s -u "${GITHUB_USERNAME}:${GITHUB_TOKEN}" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/path-to-my-repository/tags?per_page=100&page=${page}")
for row in $(jq -r '.[]' <<< "$tags"); do
    tag=$(jq -r '.name' <<< "$row")
    # I have also tried with the syntax:
    url=$(echo "${row}" | jq -r '.commit.url')
    # do stuff with $tag and $url...
done

但我收到如下错误:

解析错误:EOF 在第 2 行第 0 列 jq 处未完成的 JSON 术语:错误 (at :1):无法用字符串“name”索引字符串}解析错误: 第 1 行第 1 列不匹配的“}”

从终端输出看来,它试图以一种奇怪的方式解析$row,试图从每个子字符串中获取.name?不确定。

我假设 $(jq '.[]' &lt;&lt;&lt; "$tags") 的输出可能是有效的 JSON,我可以再次使用 jq 获取我需要的对象属性,但也许不是这样?如果我输出 ${row} 它在我看来确实是有效的 JSON,我尝试将结果粘贴到 JSON 验证器中,一切似乎都已检查...

在移至下一个对象之前,如何获取每个对象的“.name”和“.commit.url”?

谢谢

【问题讨论】:

  • jq 给出了那个错误。您是否确保 ${tags} 具有有效的 json?尝试使用 echo ${tags} 打印它
  • 它是有效的 JSON,也尝试了 -r no change - 将输出粘贴到 JSON 验证器中,签出
  • 您需要改用jq -c '.[]'
  • @oguzismail 就是这样!谢谢

标签: json bash jq


【解决方案1】:

最好避免多次调用 jq。例如:

while read -r name ; do
    read -r url
    echo "$name" "$url"
done < <( curl .... | jq -r '.[] | .name, .commit.url' )

curl .... 表示相关的 curl 调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多