使用 jq 修改包含特定字符串的对象中的值

Modify value in the object containing a particular string using jq

我正在尝试修改一个大型 json 文件(一个 Grafana 仪表板),替换单个值,然后输出包含更改的整个文件。我该怎么做?

你可以在这里看到我要编辑的值。实际文件很大,所以还有很多其他顶层值,但我只需要编辑"templating"块下的特定项目。

"templating": {
    "list": [
      {
        "allValue": ".*",
        "current": {},
        "datasource": "$Source",
        "hide": 0,
        "includeAll": false,
        "label": null,
        "multi": true,
        "name": "node",
        "options": [],
        "query": "label_values(node_boot_time{env=~\"$env\"}, instance)",
        "refresh": 1,
        "regex": "",
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      },
      {
        "allValue": null,
        "current": {
          "tags": [],
          "text": "",
          "value": ""
        },
        "datasource": "$Source",
        "definition": "label_values(env)",
        "hide": 0,
        "includeAll": true,
        "label": "env",
        "multi": false,
        "name": "env",
        "options": [],
        "query": "label_values(env)",
        "refresh": 1,
        "regex": "",
        "skipUrlSync": false,
        "sort": 1,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      },
      {
        "current": {
          "tags": [],
          "text": "",
          "value": ""
        },
        "hide": 0,
        "includeAll": false,
        "label": null,
        "multi": false,
        "name": "Source",
        "options": [],
        "query": "prometheus",
        "refresh": 1,
        "regex": "",
        "skipUrlSync": false,
        "type": "datasource"
      }
    ]
  },

我需要更改的部分是包含 "query": "label_values(env)", 的块,我只需要更改 "regex": "",

的值

我试过:

jq '.templating.list[] | select(.name == "env") |= . + {regex:"*"}' "dashboard.json" > test.json 

问题是它只打印“.list[]”元素而不是整个文件。我需要能够对具有相同块但不一定在同一位置的多个其他文件进行此更改,所以我不能只按索引号 select。

以上脚本的输出:

{
  "allValue": ".*",
  "current": {},
  "datasource": "$Source",
  "hide": 0,
  "includeAll": false,
  "label": null,
  "multi": true,
  "name": "node",
  "options": [],
  "query": "label_values(node_boot_time{env=~\"$env\"}, instance)",
  "refresh": 1,
  "regex": "",
  "sort": 0,
  "tagValuesQuery": "",
  "tags": [],
  "tagsQuery": "",
  "type": "query",
  "useTags": false
}
{
  "allValue": null,
  "current": {
    "tags": [],
    "text": "",
    "value": ""
  },
  "datasource": "$Source",
  "definition": "label_values(env)",
  "hide": 0,
  "includeAll": true,
  "label": "env",
  "multi": false,
  "name": "env",
  "options": [],
  "query": "label_values(env)",
  "refresh": 1,
  "regex": "*",
  "skipUrlSync": false,
  "sort": 1,
  "tagValuesQuery": "",
  "tags": [],
  "tagsQuery": "",
  "type": "query",
  "useTags": false
}
{
  "current": {
    "tags": [],
    "text": "",
    "value": ""
  },
  "hide": 0,
  "includeAll": false,
  "label": null,
  "multi": false,
  "name": "Source",
  "options": [],
  "query": "prometheus",
  "refresh": 1,
  "regex": "",
  "skipUrlSync": false,
  "type": "datasource"
}

您的预期输出与您对问题的描述不完全相符。如果您的要求是在 templating 列表中查找,请在下面找到包含 "label_values(env)" 的查询并将 regex 更新为 ""。要将其更改为 *,请使用 regex = "*"

.templating.list[] |= ( select(.query == "label_values(env)").regex = "")

关键是使用正确的路径,使用select运算符获取对象,使用|=运算符

进行更新

jq-play snippet

位置|=更早以保留原来的结构。

.templating.list[] |= (select(.name == "env") .regex = "*")

Online demo