使用jq条件更新数组元素

5

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

例如,我想查找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 . | jq '[.[].discoveredEntities[] | if (.name=="weather") then (.checked = "false") else . end]' ./test.json。但它只返回部分已更新天气的 checked = false。[ { "name": "weather", "checked": "false", "checkedBeforeEdit": false, "storeFieldsAsStrings": false }, { "name": "weather_2", "checked": true, "checkedBeforeEdit": false, "storeFieldsAsStrings": false } ] - CLO
3个回答

4
我搞定了。
jq '[.[].discoveredEntities[] |= if (.name=="weather") then (.checked = "false") else . end]'\
    ./test.json

1
在这种情况下,您不需要外部方括号[],因为您正在将结果放入数组中。但由于主体只是赋值,因此初始输入将始终返回。您最终会得到更新后的原始输入,但以数组形式呈现。 - Jeff Mercado
1
使用布尔值 false 而不是字符串 "false" 会更符合文档的一致性。 - peak

3

对于这类更新,如果您能先定位需要更新的项目,再进行更新,将会更加直观易懂。

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

虽然更新工作正常,但会产生意外的副作用,即返回经过过滤的结果。有没有办法将未修改的项目包含在结果集中? - Sergii Shymko

0

在这里使用map可以得到一个非常直接但有些平凡的解决方案:

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

请注意,在这里使用false而不是"false"显然更为合适。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接