I'm trying to improve on a jq reduce, but finding that some of the returned data is nested and the code I'm using breaks on that.
This is where I've got the jq code from: https://github.com/influxdata/telegraf/tree/master/plugins/inputs/powerdns_recursor
Taking tonumber
off I get the following clipped output:
[...]
"x-ourtime8-16": "0",
"zone-disallowed-notify": "0",
"response-by-qtype": [
{
"name": "A",
"value": "8958"
},
{
"name": "NS",
"value": "6"
},
[...]
The original code, with tonumber
left in:
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)})'
The output I'm after:
[...]
"x-ourtime8-16": 0,
"zone-disallowed-notify": 0,
"response-by-qtype.A": 8958,
"response-by-qtype.NS": 6,
[...]
I've spent some time Googling jq and nested input, but I don't want the index numbers this gave me in the names. I'm hoping a small tweak will do the trick.
CodePudding user response:
You can convert numeric strings to numbers using:
if type == "string" then . as $in | try tonumber catch $in else . end
As a post-processing step, you could use walk
as a wrapper:
walk(if type == "string" then . as $in | try tonumber catch $in else . end)
CodePudding user response:
To transform this input :
{
"x-ourtime8-16": "0",
"zone-disallowed-notify": "0",
"response-by-qtype": [
{
"name": "A",
"value": "8958"
},
{
"name": "NS",
"value": "6"
}
]
}
You can run :
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
to get :
{
"x-ourtime8-16": 0,
"zone-disallowed-notify": 0,
"response-by-qtype.A": 8958,
"response-by-qtype.NS": 6
}