I'm trying to export data from consul kv into json with a nested object for each level of depth in consul.
Example json returned from consul:
[
{
"LockIndex": 0,
"Key": "foobar/testing",
"Flags": 0,
"Value": "xxxxx",
"CreateIndex": 833,
"ModifyIndex": 833
},
{
"LockIndex": 0,
"Key": "foobar/bazbar",
"Flags": 0,
"Value": "xxxxx",
"CreateIndex": 833,
"ModifyIndex": 833
}
]
Desired JSON:
[
{
"foobar": {
"testing": "xxxxx",
"bazbar": "xxxxx"
}
}
]
I'm sort of close with jq '.[] | objects | {Key: .Key | split("/"), Value: .Value}'
but I'm just not understanding how I can recurse based on a split() of .Key and create nested objects. I think I'll also need to sort_by(.Key) to handle out of order data, unless I can | add
arbitrarily and have jq resolve the structure.
I realize xxxxx
is base64 encoded, and hopefully, base64d
will get merged soon but until then I think I can handle decoding this with shell post-processing.
The following produces the JSON object of interest in the particular case you give, but also provides a reasonable generalization in case there is more than one "foobar" prefix:
map( . as $o | .Key | split("/") | {(.[0]): {(.[1]): ($o|.Value) }} )
| reduce .[] as $o
( {};
($o|keys[0]) as $key | . + { ($key): (.[$key] + $o[$key]) } )
Output:
{
"foobar": {
"testing": "xxxxx",
"bazbar": "xxxxx"
}
}
Here is a solution that uses reduce, split and setpath
[
reduce (.[] | [(.Key | split("/")), .Value]) as [$p,$v] (
{}
; setpath($p; $v)
)
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With