jq 条件更新数组元素

jq conditional update an array element

我想根据同一数组中另一个元素的值有条件地更新一个元素值。

例如,我想找到 name=="weather" 并将 checked 从 "true" 更改为 "false"

[
  {
    "originalSourceId": null,
    "sourceConnection": {
      "id": null,
      "version": null,
      "properties": [
        {
          "id": null,
          "version": null
        }
      ],
      "name": "POSTGRESQL",
      "businessName": null
    },
    "checked": true,
    "newlyAdded": false,
    "discoveredEntities": [
      {
        "name": "weather",
        "checked": true,
        "checkedBeforeEdit": false,
        "storeFieldsAsStrings": false
      },
      {
        "name": "weather_2",
        "checked": true,
        "checkedBeforeEdit": false,
        "storeFieldsAsStrings": false
      }
    ],
    "defaultLevel": "MANAGED"
  }
]

对于名称为 "weather"

的同一对象,选中的元素将更新为 "false"
[
  {
    "originalSourceId": null,
    "sourceConnection": {
      "id": null,
      "version": null,
      "properties": [
        {
          "id": null,
          "version": null
        }
      ],
      "name": "POSTGRESQL",
      "businessName": null
    },
    "checked": true,
    "newlyAdded": false,
    "discoveredEntities": [
      {
        "name": "weather",
        "checked": false,
        "checkedBeforeEdit": false,
        "storeFieldsAsStrings": false
      },
      {
        "name": "weather_2",
        "checked": true,
        "checkedBeforeEdit": false,
        "storeFieldsAsStrings": false
      }
    ],
    "defaultLevel": "MANAGED"
  }
]

想通了。

jq '[.[].discoveredEntities[] |= if (.name=="weather") then (.checked = "false") else . end]'\
    ./test.json

对于这些类型的更新,如果您这样想,则更容易形象化,首先找到要更新的项目,然后再进行更新。

 (.[].discoveredEntities[] | select(.name == "weather").checked) = false
#[ locate the items to update                         ]
#                                                      [ update them   ]

在这里使用 map 会产生一个非常简单但有点乏味的解决方案:

map( .discoveredEntities |=
        map(if .name == "weather" then .checked = false else . end))

注意这里用false显然比"false"更合适。