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"
    }
}

一种方法使用 reducesetpath 从原始对象的键构建新对象:

$ 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" 等等。