jq:从平面键创建 JSON 对象
jq: Create JSON Object from flat keys
如何使用 jq 从对象中的平面键创建嵌套的 JSON 对象?
我的输入是
{
"foo.bar": "lorem",
"foo.baz": "ipsum",
"bar.foo": "dolor"
}
输出应该类似于
{
"foo": {
"bar": "lorem",
"baz": "ipsum"
},
"bar": {
"foo": "dolor"
}
}
一种方法使用 reduce
和 setpath
从原始对象的键构建新对象:
$ jq '. as $orig | reduce keys[] as $key ({}; setpath($key | split("."); $orig[$key]))' input.json
{
"bar": {
"foo": "dolor"
},
"foo": {
"bar": "lorem",
"baz": "ipsum"
}
}
工作原理
reduce
每个键在其正文中调用一次表达式。第一次,.
被设置为一个空对象,每次都是前一次调用返回的主体。每次调用都会将当前键拆分为一个数组,setpath
使用该数组作为路径,使用原始对象中的相应值在 .
中进行设置。
所以结果是每次逐渐建立一个元素:
.
= {}
和 $key
= "foo.bar"
-> .
= {"foo":{"bar":"lorem"}}
和 $key
= "foo.baz"
等等。
如何使用 jq 从对象中的平面键创建嵌套的 JSON 对象?
我的输入是
{
"foo.bar": "lorem",
"foo.baz": "ipsum",
"bar.foo": "dolor"
}
输出应该类似于
{
"foo": {
"bar": "lorem",
"baz": "ipsum"
},
"bar": {
"foo": "dolor"
}
}
一种方法使用 reduce
和 setpath
从原始对象的键构建新对象:
$ jq '. as $orig | reduce keys[] as $key ({}; setpath($key | split("."); $orig[$key]))' input.json
{
"bar": {
"foo": "dolor"
},
"foo": {
"bar": "lorem",
"baz": "ipsum"
}
}
工作原理
reduce
每个键在其正文中调用一次表达式。第一次,.
被设置为一个空对象,每次都是前一次调用返回的主体。每次调用都会将当前键拆分为一个数组,setpath
使用该数组作为路径,使用原始对象中的相应值在 .
中进行设置。
所以结果是每次逐渐建立一个元素:
.
= {}
和 $key
= "foo.bar"
-> .
= {"foo":{"bar":"lorem"}}
和 $key
= "foo.baz"
等等。