Using jq to split a string into nested objects

I am trying to export data from consul kv to json with a nested object for each depth level in the consul.

An json example returned from the 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 kinda close to jq '.[] | objects | {Key: .Key | split("/"), Value: .Value}' jq '.[] | objects | {Key: .Key | split("/"), Value: .Value}' jq '.[] | objects | {Key: .Key | split("/"), Value: .Value}' , but I just don’t understand how I can recursively rely on split (). Key and create nested objects. I think I will also need sort_by (.Key) to process the data out of order if I cannot | add | add arbitrarily and not allow jq structure.

I understand that xxxxx is base64 encoded, and hopefully base64d will be merged soon, but until then I think I can handle decoding with subsequent shell processing.

+6
source share
2 answers

The following is a JSON object that is of interest for the specific case that you are giving, but also provides a reasonable generalization if more than one foobar prefix exists:

 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" } } 
+6
source

Here is a solution that uses reduce , split and setpath

 [ reduce (.[] | [(.Key | split("/")), .Value]) as [$p,$v] ( {} ; setpath($p; $v) ) ] 
0
source

All Articles