在jq中用节点替换从根开始的路径

Substituting nodes for paths from root in jq

如何使用 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"
    ]
  }
}

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

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

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

jqplay demo