当只能通过 select() 到达键的路径时,如何使用 jq 更改 json 中的值

当只能通过 select() 到达键的路径时,如何使用 jq 更改 json 中的值

让我们从一个例子输出开始:

{
  "title": "The Flash (2014)",
  "alternateTitles": [
    {
      "title": "The Flash",
      "seasonNumber": -1
    }
  ],
  "sortTitle": "flash 2014",
  "seasonCount": 7,
  "totalEpisodeCount": 154,
  "episodeCount": 142,
  "episodeFileCount": 0,
  "sizeOnDisk": 0,
  "status": "continuing",
  "overview": "After being struck by lightning, Barry Allen wakes up from his coma to discover he's been given the power of super speed, becoming the Flash, fighting crime in Central City.",
  "nextAiring": "2021-05-19T00:00:00Z",
  "previousAiring": "2021-05-12T00:00:00Z",
  "network": "The CW",
  "airTime": "20:00",
  "images": [
    {
      "coverType": "banner",
      "url": "/MediaCover/37/banner.jpg?lastWrite=637552858236774582",
      "remoteUrl": "https://artworks.thetvdb.com/banners/graphical/279121-g7.jpg"
    },
    {
      "coverType": "poster",
      "url": "/MediaCover/37/poster.jpg?lastWrite=637552858237654584",
      "remoteUrl": "https://artworks.thetvdb.com/banners/posters/279121-5.jpg"
    },
    {
      "coverType": "fanart",
      "url": "/MediaCover/37/fanart.jpg?lastWrite=637552858239814588",
      "remoteUrl": "https://artworks.thetvdb.com/banners/fanart/original/279121-9.jpg"
    }
  ],
  "seasons": [
    {
      "seasonNumber": 0,
      "monitored": false,
      "statistics": {
        "episodeFileCount": 0,
        "episodeCount": 0,
        "totalEpisodeCount": 8,
        "sizeOnDisk": 0,
        "percentOfEpisodes": 0
      }
    },
    {
      "seasonNumber": 1,
      "monitored": true,
      "statistics": {
        "previousAiring": "2015-05-20T00:00:00Z",
        "episodeFileCount": 0,
        "episodeCount": 0,
        "totalEpisodeCount": 23,
        "sizeOnDisk": 0,
        "percentOfEpisodes": 0
      }
    },
    {
      "seasonNumber": 2,
      "monitored": true,
      "statistics": {
        "previousAiring": "2016-05-25T00:00:00Z",
        "episodeFileCount": 0,
        "episodeCount": 0,
        "totalEpisodeCount": 23,
        "sizeOnDisk": 0,
        "percentOfEpisodes": 0
      }
    },
    {
      "seasonNumber": 3,
      "monitored": true,
      "statistics": {
        "previousAiring": "2017-05-24T00:00:00Z",
        "episodeFileCount": 0,
        "episodeCount": 0,
        "totalEpisodeCount": 23,
        "sizeOnDisk": 0,
        "percentOfEpisodes": 0
      }
    },
    {
      "seasonNumber": 4,
      "monitored": true,
      "statistics": {
        "previousAiring": "2018-05-23T00:00:00Z",
        "episodeFileCount": 0,
        "episodeCount": 0,
        "totalEpisodeCount": 23,
        "sizeOnDisk": 0,
        "percentOfEpisodes": 0
      }
    },
    {
      "seasonNumber": 5,
      "monitored": true,
      "statistics": {
        "previousAiring": "2019-05-15T00:00:00Z",
        "episodeFileCount": 0,
        "episodeCount": 0,
        "totalEpisodeCount": 22,
        "sizeOnDisk": 0,
        "percentOfEpisodes": 0
      }
    },
    {
      "seasonNumber": 6,
      "monitored": true,
      "statistics": {
        "previousAiring": "2020-05-13T00:00:00Z",
        "episodeFileCount": 0,
        "episodeCount": 0,
        "totalEpisodeCount": 19,
        "sizeOnDisk": 0,
        "percentOfEpisodes": 0
      }
    },
    {
      "seasonNumber": 7,
      "monitored": true,
      "statistics": {
        "nextAiring": "2021-05-19T00:00:00Z",
        "previousAiring": "2021-05-12T00:00:00Z",
        "episodeFileCount": 0,
        "episodeCount": 0,
        "totalEpisodeCount": 13,
        "sizeOnDisk": 0,
        "percentOfEpisodes": 0
      }
    }
  ],
  "year": 2014,
  "path": "/home/cas/plex-media/series/The Flash (2014)",
  "profileId": 6,
  "languageProfileId": 1,
  "seasonFolder": true,
  "monitored": false,
  "useSceneNumbering": false,
  "runtime": 42,
  "tvdbId": 279121,
  "tvRageId": 36939,
  "tvMazeId": 13,
  "firstAired": "2014-10-07T00:00:00Z",
  "lastInfoSync": "2021-05-16T03:08:01.309493Z",
  "seriesType": "standard",
  "cleanTitle": "theflash2014",
  "imdbId": "tt3107288",
  "titleSlug": "the-flash-2014",
  "certification": "TV-PG",
  "genres": [
    "Action",
    "Adventure",
    "Drama",
    "Science Fiction"
  ],
  "tags": [],
  "added": "2021-04-29T09:37:02.970046Z",
  "ratings": {
    "votes": 6551,
    "value": 8.7
  },
  "qualityProfileId": 6,
  "id": 37
}

现在,我想将的值更改.seasons | .[] | select(.seasonNumber==2).monitored为 false。我可以使用以下命令来实现:

# '.[] | select(.title==$TITLE)' is used to get example output
# '--argjson SEASON "$((season-1))"' will be 2 in this case (giving 3rd object, which is indeed season 2)

[api request] | jq -rM --arg TITLE "${info[$((series-1))]}" --arg SEASON "$((season-1))" '.[] | select(.title==$TITLE).seasons | .[] | select(.seasonNumber==$SEASON) | .monitored = false'

{
  "seasonNumber": 2,
  "monitored": false,
  "statistics": {
    "previousAiring": "2016-05-25T00:00:00Z",
    "episodeFileCount": 0,
    "episodeCount": 0,
    "totalEpisodeCount": 23,
    "sizeOnDisk": 0,
    "percentOfEpisodes": 0
  }
}

但是,我不想要这个输出。我现在只得到对象本身。我想要完整的示例输出,以及更改的值。我认为问题出在后面|.seasons但我不知道如何修复它。

我的目标是示例输出,但监控更改为false(并且只针对我想要的季节)

编辑:应该提到我想直接正确地在终端中获取输出。因此不要在过程结束时或过程中保存到文件中(然后在新命令中使用它)。但是多个命令和变量是可以的。

回答穆鲁的问题:

#for simplicity I changed to values of the --arg's to actual value's
jq --arg TITLE "The Flash (2014)" --arg SEASON "2" '.[] | select(.title==$TITLE).seasons[] |= (select(.seasonNumber==$SEASON) |= (.monitored = false))'

首先它输出的[api request][api request] | jq -rM --arg TITLE "The Flash (2014)" '.[] | select(.title==$TITLE)'

其次,它...不会改变值。忽略完整的 api 输出而不是仅忽略示例输出,它仍然"monitored": true,显示"seasonNumber": 2,

编辑2:

我让它工作了:

jq --arg TITLE "The Flash (2014)" --argjson SEASON "4" '.[] | select(.title==$TITLE) | .seasons[] |= (select(.seasonNumber==$SEASON) |= (.monitored = false))'

区别:

  1. select(.title==$TITLE).seasons[]->select(.title==$TITLE) | .seasons[]
  2. --arg SEASON "4"->--argjson SEASON "4"

答案1

您想要的是本质上两个更新(更新匹配的季节对象,然后用该对象更新季节数组)。所以:

.[] | select(.title==$TITLE).seasons[] |= (select(.seasonNumber==$SEASON) |= (.monitored = false))

这里,内部更新(|=)更新select输入数组中的 ed 季节,外部|=使用结果更新数组。

相关内容