【问题标题】:Modify value in the object containing a particular string using jq使用 jq 修改包含特定字符串的对象中的值
【发布时间】:2020-05-18 13:13:31
【问题描述】:

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

您可以在此处查看我要编辑的值。实际文件很大,所以还有很多其他顶级值,但我只需要编辑“模板”块下的特定项目即可。

"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[]”元素而不是整个文件。我需要能够对具有相同块但不一定在同一个位置的多个其他文件进行此更改,因此我不能只按索引号进行选择。

上述脚本的输出:

{
  "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"
}

【问题讨论】:

    标签: json jq edit


    【解决方案1】:

    提前定位|=以保留原始结构。

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

    Online demo

    【讨论】:

    • 行得通,谢谢!另外我不知道jq play,非常有帮助!
    【解决方案2】:

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

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

    关键是使用正确的路径,使用|=操作符使用select操作符获取要更新的对象

    jq-play snippet

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      相关资源
      最近更新 更多