Json 替换jq中没有精确路径的子键
JSON文件示例:Json 替换jq中没有精确路径的子键,json,nested,key,updates,jq,Json,Nested,Key,Updates,Jq,JSON文件示例: { "u": "stuff", "x": [1,2,3], "y": { "field": "value" }, "z": { "zz": { "name": "change me", "more": "stuff" }, "randomKey": { "name": "change me", "random": "more stuff" } } } 如
{
"u": "stuff",
"x": [1,2,3],
"y": {
"field": "value"
},
"z": {
"zz": {
"name": "change me",
"more": "stuff"
},
"randomKey": {
"name": "change me",
"random": "more stuff"
}
}
}
如何将所有名称字段更新为“something”,保持JSON文件的其余部分不变
{
"u": "stuff",
"x": [1,2,3],
"y": {
"field": "value"
},
"z": {
"zz": {
"name": "something",
"more": "stuff"
},
"randomKey": {
"name": "something",
"random": "more stuff"
}
}
}
使用直接路径时,这将很容易,但父关键点(在这种情况下为z和randomKey)会有所不同
我试过这样的方法:
jq '.z | .. | .name? |= "something"' file.json
它会更新名称,但也会放入所有递归内容。如果可以在任何地方更改“name”字段,您可以使用
walk/1
:
walk(if type == "object" and has("name") then .name = "something" else . end)
请注意,walk/1
仅在JQ1.5发布后才包含在jq中。如果您的jq没有它,那么您可以在上找到它的定义,例如
如果只想修改“z”上下文中的“name”字段,请考虑:
.z |= with_entries(if .value.name?
then .value.name = "something"
else . end)
假设
z
中的每个值都有name属性,则可以执行以下操作:
$ jq --arg newname 'something' '.z[].name = $newname' input.json
在对象上使用[]
将生成该对象中包含的所有值。对于这些值中的每一个,我们只是将名称
设置为新名称
如果您需要对更新的对象更具选择性,则必须为要更新的对象添加更多条件。一般来说,我会使用peak的方法,但这里有另一种方法,可以使用类似于第一种方法的结构来实现,假设我们只想更新已经具有
名称
属性的对象:
$ jq --arg newname 'something' '(.z[] | select(has("name")).name) = $newname' input.json
将赋值的左括号括起来很重要,我们不想在赋值之前更改上下文,否则我们将看不到剩余的结果