Through another SO thread, I found how to "flatten" JSON using jq. I am looking how to do the inverse, i.e., "unflatten" it.
Original JSON has mixed levels in the hierarchy, e.g.:
{
"X1": {
"X1o1": {
"X1o1o1": "abc",
"X1o1o2": "def"
},
"X1o2" : {
"X1o2o1" : "ghi",
"X1o2o2": "jkl"
},
"X1o3": "mno"
},
"X2": "pqr"
}
As https://jqplay.org/s/Eo6h_3V8PO shows, for working with other colleagues, I need to "flatten" that structure () using
reduce (tostream|select(length==2)) as $i ({}; .[[$i[0][]|tostring]|join("_")] = $i[1] )
to produce:
{
"X1_X1o1_X1o1o1": "abc",
"X1_X1o1_X1o1o2": "def",
"X1_X1o2_X1o2o1": "ghi",
"X1_X1o2_X1o2o2": "jkl",
"X1_X1o3": "mno",
"X2": "pqr"
}
What I need help is how to transform such an output JSON back to the original form using jq?
I see that the split
only works with strings as in tostring | split("_")
.
Any pointers and/or examples to guide me in the right direction would be much appreciated.
With your sample input, the filter:
reduce to_entries[] as $kv ({}; setpath($kv.key|split("_"); $kv.value))
produces:
{
"X1": {
"X1o1": {
"X1o1o1": "abc",
"X1o1o2": "def"
},
"X1o2": {
"X1o2o1": "ghi",
"X1o2o2": "jkl"
},
"X1o3": "mno"
},
"X2": "pqr"
}