使用 jq 过滤 JSON 个外部对象,仅包括来自内部数组的一个最大对象

Filter JSON outer objects including only one maximal object from inner array with jq

我有一个稍微修改过的 JSON 文件,其中包含来自 https://api.ipsw.me/v2.1/firmwares.json 的 iOS 固件信息。这是一个简化版本:

输入

{
  "AppleTV5,3": {
    "firmwares": [
      {
        "version": "9.2",
        "buildid": "13Y234"
      },
      {
        "version": "9.1.1",
        "buildid": "13U717"
      },
      {
        "version": "9.1",
        "buildid": "13U85"
      }
    ],
    "bdid": 52,
    "name": "Apple TV 4 (2015)"
  },
  "AppleTV3,2": {
    "firmwares": [
      {
        "version": "8.4.1",
        "buildid": "12H523"
      },
      {
        "version": "8.3",
        "buildid": "12F69"
      }
    ],
    "bdid": 0,
    "name": "Apple TV 3 (2013)"
  },
  "AppleTV3,1": {
    "firmwares": [
      {
        "version": "8.4.1",
        "buildid": "12H523"
      },
      {
        "version": "8.3",
        "buildid": "12F69"
      },
      {
        "version": "8.2",
        "buildid": "12D508"
      }
    ],
    "bdid": 0,
    "name": "Apple TV 3"
  }
}

我想编写一个 jq 查询,returns 每个外部对象只包含 firmwares 数组中的最新固件对象。例如:

期望输出

{
  "AppleTV5,3": {
    "firmwares": [
      {
        "version": "9.2",
        "buildid": "13Y234"
      }
    ],
    "bdid": 52,
    "name": "Apple TV 4 (2015)"
  },
  "AppleTV3,2": {
    "firmwares": [
      {
        "version": "8.4.1",
        "buildid": "12H523"
      }
    ],
    "bdid": 0,
    "name": "Apple TV 3 (2013)"
  },
  "AppleTV3,1": {
    "firmwares": [
      {
        "version": "8.4.1",
        "buildid": "12H523"
      }
    ],
    "bdid": 0,
    "name": "Apple TV 3"
  }
}

我可以获得最新的 firmwares 个对象的列表:

.[].firmwares | max_by(.version)

我可以只从 version 中获取值:

.[].firmwares | map(.version | values) | max

而且我可以获得 firmwares 匹配特定 version:

的外部 AppleTV 对象
[ . | to_entries[] | .value.firmwares |= map ( select ( .version == "8.3" ) ) ] | from_entries

但我似乎无法组合这些技术来获得我想要的输出。有人可以帮忙吗?

您应该将其视为更新 firmwares 数组。我们正在使用已选择最大版本的过滤版本对其进行更新。

.[].firmwares |= [ max_by(.version | split(".") | map(tonumber)) // empty ]

这是一个解决方案,它使用 reduce 访问对象的每个键并将相应的 .firmwares 更新为最新版本

reduce keys[] as $i (
    .
  ; .[$i].firmwares |= [max_by(.version)]
)