【问题标题】:Substituting nodes for paths from root in jq在jq中用节点替换来自根的路径
【发布时间】:2021-07-14 02:58:00
【问题描述】:

如何使用 jq 将树中的某个匹配节点替换为从根节点到该节点的路径?

使用walk,只能访问从当前节点到树下的路径:

https://jqplay.org/s/BVOQ-xa1JM:

walk(if type == "object" and has("d") then .d = path(.) else . end)

输入:

{"a": {"b": 1, "c": {"d": 2}}, "e": {"d}

结果:

{
  "a": {
    "b": 1,
    "c": {
      "d": []
    }
  },
  "e": {
    "d": []
  }
}

想要的结果是:

{
  "a": {
    "b": 1,
    "c": {
      "d": ["a", "c"]
    }
  },
  "e": {
    "d": ["e"]
  }
}

注意:这不能导致整个树的重复,如下所示:

(paths | select(.[-1] == "d")) as $f | setpath($f; $f[:-1])

什么原因:

{
  "a": {
    "b": 1,
    "c": {
      "d": [
        "a",
        "c"
      ]
    }
  },
  "e": {
    "d": 3
  }
}
{
  "a": {
    "b": 1,
    "c": {
      "d": 2
    }
  },
  "e": {
    "d": [
      "e"
    ]
  }
}

【问题讨论】:

  • 我已将示例结果更正为从根到 c 的路径为 ["a","c"]

标签: arrays json path jq


【解决方案1】:

您的预期输出不正确,因为 b 不涉及从根目录到 d 的向下路径。您可以在--null-input 模式下使用涉及setpath()paths 函数,即使用jq -n

( inputs | paths | select(.[-1] == "d")) as $f | setpath($f; $f[:-1])

这个想法是在变量$f 中构造到d 的路径通道,并使用set path 函数来设置相同的值。 [:-1] 部分修剪离开叶节点的数组中的最后一个条目。

jqplay demo

【讨论】:

  • 不幸的是,这不是一个完整的解决方案:对于d 的多个案例,这会导致整个树的重复。检查我编辑的问题。
猜你喜欢
  • 2016-09-17
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-12
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
相关资源
最近更新 更多