减少嵌套 json(PowerDNS 统计数据)

Reduce nested json (PowerDNS stats)

我试图改进 jq reduce,但发现一些返回的数据是嵌套的,我正在使用的代码中断了。

这是我从中获得 jq 代码的地方:https://github.com/influxdata/telegraf/tree/master/plugins/inputs/powerdns_recursor

关闭 tonumber 我得到以下剪切输出:

[...]
  "x-ourtime8-16": "0",
  "zone-disallowed-notify": "0",
  "response-by-qtype": [
    {
      "name": "A",
      "value": "8958"
    },
    {
      "name": "NS",
      "value": "6"
    },
[...]

原代码,tonumber留在:

curl -s -H 'X-API-Key: <key>' http://127.0.0.1:8082/api/v1/servers/localhost/statistics | jq 'reduce .[] as $item ({}; . + { ($item.name): ($item.value|tonumber)})'

我想要的输出:

[...]
  "x-ourtime8-16": 0,
  "zone-disallowed-notify": 0,
  "response-by-qtype.A": 8958,
  "response-by-qtype.NS": 6,
[...]

我花了一些时间在谷歌上搜索 jq 和嵌套输入,但我不想要名称中给我的索引号。我希望稍微调整一下就能解决问题。

您可以使用以下方法将数字字符串转换为数字:

if type == "string" then . as $in | try tonumber catch $in else . end

作为 post-processing 步骤,您可以使用 walk 作为包装器:

walk(if type == "string" then . as $in | try tonumber catch $in else . end)

要转换此输入:

{
  "x-ourtime8-16": "0",
  "zone-disallowed-notify": "0",
  "response-by-qtype": [
    {
      "name": "A",
      "value": "8958"
    },
    {
      "name": "NS",
      "value": "6"
    }
  ]
}

你可以 运行 :

jq ' to_entries |
     map(if (.value | type) == "string"
         then .value |= tonumber
         else .key as $key | .value[] |
              .name  |= $key+"."+. |
              .value |= tonumber
         end
     ) | from_entries
' input.json

获得:

{
  "x-ourtime8-16": 0,
  "zone-disallowed-notify": 0,
  "response-by-qtype.A": 8958,
  "response-by-qtype.NS": 6
}