gpt4 book ai didi

jq:递归重命名键

转载 作者:行者123 更新时间:2023-12-05 00:03:14 29 4
gpt4 key购买 nike

我的 JSON 结构如下所示。 “groups”可以嵌套在“items”下任意深度,因此我需要编写一个表达式来访问每个“groups”和“items”属性(或父对象);静态路径不行。

{
"groups": [{
"name": "group1",
"items": [
{
"name": "item1",
"groups": [
{
"name": "nestedGroup1",
"items": [
{
"name": "nestedItem1",
"groups": []
},{
"name": "nestedItem2",
"groups": []
}]
}
]
},
{
"name": "item2",
"groups": []
}
]
}]
}

如何以递归方式重命名所有“组”以将“newGroups”和“items”重命名为“newItems”?如果您将其分解,我知道我需要在每个级别创建新 key 并删除旧 key ,但我无法表达这一点。我已经尝试了几种变体,例如

.. |= if type == "object" and has("groups") then . + { newGroups: .groups } else . end

执行第一步,但这会导致将顶级“groups”值复制到“newGroups”,同时保持嵌套“groups”不变。 “groups”中的剩余值然后也获得兄弟“newGroups”及其嵌套的“groups”,没有“newGroups”兄弟等。

根据观察,我的理解是首先评估由 .. 运算符生成的路径,因此永远不会遍历新添加的键。所以我尝试了上面的变体,将 .. 替换为 recurse 有参数和没有参数,认为它会获取 RHS 产生的值并将其反馈回到 LHS,像这样:

{ newGroups: .groups } | recurse |= if type == "object" and has("groups") then . + { newGroups: .groups } elif type == "object" and has("items") then . + { newItems: .items } else . end

结果更近了,但还是那么远。递归类的作品,但只适用于已经存在的键;附加到对象的新对象未被访问。

我也试过弄乱 pathsgetpathsetpath 来尝试以这种方式解决问题,但遇到了问题那里也一样。请帮助我摆脱困境!

最佳答案

这在 jq - FAQ 中有很好的解释在使用 walk/1 的递归遍历下。我使用了来自 jq-builtinswalk/1 的标准实现页面,因为我的版本默认没有它。

来自 walk/1 的文档 - 递归遍历输入的 JSON 实体,将遇到的每个键 k 更改为 (k|filter),其中filter是指定的过滤器,可以是任意的jq表达式。

我在脚本中使用了以下过滤器

# Apply f to composite entities recursively, and to atoms
def walk(f):
. as $in
| if type == "object" then
reduce keys_unsorted[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;

def translate_keys(f):
walk( if type == "object" then
with_entries( if .key | contains("groups") then
.key |= "newgroups"
elif .key | contains("items") then
.key |= "newitems"
else
. end
)
else
. end
);


translate_keys(.)

然后运行脚本

jq -f script.jq json

产生了您需要的结果。

关于jq:递归重命名键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51091583/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com