首页 > 解决方案 > 如何使用 jq 对对象进行展平的逆运算?

问题描述

通过另一个 SO 线程,我发现了如何使用 jq “扁平化” JSON。我正在寻找如何做相反的事情,即“展开”它。

原始 JSON 在层次结构中具有混合级别,例如:

{
  "X1": {
    "X1o1": {
      "X1o1o1": "abc",
      "X1o1o2": "def"
    },
    "X1o2" : {
      "X1o2o1" : "ghi",
      "X1o2o2": "jkl"
    },
    "X1o3": "mno"
  },
  "X2": "pqr"
}

正如https://jqplay.org/s/Eo6h_3V8PO所示,为了与其他同事一起工作,我需要使用“扁平化”该结构 ()

reduce (tostream|select(length==2)) as $i ({}; .[[$i[0][]|tostring]|join("_")] = $i[1] )

生产:

{
  "X1_X1o1_X1o1o1": "abc",
  "X1_X1o1_X1o1o2": "def",
  "X1_X1o2_X1o2o1": "ghi",
  "X1_X1o2_X1o2o2": "jkl",
  "X1_X1o3": "mno",
  "X2": "pqr"
}

我需要帮助的是如何使用 jq 将这样的输出 JSON 转换回原始形式?

我看到split唯一适用于字符串的tostring | split("_").

任何指导我正确方向的指针和/或示例将不胜感激。

标签: jsonnestedkeyjqinverse

解决方案


使用您的样本输入,过滤器:

reduce to_entries[] as $kv ({}; setpath($kv.key|split("_"); $kv.value))

产生:

{
  "X1": {
    "X1o1": {
      "X1o1o1": "abc",
      "X1o1o2": "def"
    },
    "X1o2": {
      "X1o2o1": "ghi",
      "X1o2o2": "jkl"
    },
    "X1o3": "mno"
  },
  "X2": "pqr"
}


推荐阅读