请协助jq的新手。 :)
我必须更新具有特定名称的字段,该名称可能会出现在JSON结构的任何级别上-可能不会。类似于下面所有JSON中的* .description字段:
{
"a": {
"b": [{
"name": "b0",
"description": "b0 has description"
},
{
"name": "b1",
"description": null
},
{
"name": "b2"
}
],
"description": null
},
"s": "Some string value"
}
如果只有空值,我需要用一些伪值更新“描述”值,但是不要触摸现有值,并且不要在不存在的地方创建新字段。因此,这种情况下的预期结果是:
{
"a": {
"b": [{
"name": "b0",
"description": "b0 has description"
},
{
"name": "b1",
"description": "DUMMY DESCRIPTION"
},
{
"name": "b2"
}
],
"description": "DUMMY DESCRIPTION"
},
"s": "Some string value"
}
.a.b [0] .description保留不变,因为它存在且不为null; .a.b [1] .description和.a.description被强制为“ Dummy Description”,因为这些字段存在并且为空;和.a.b [2]以及根级别保持不变,因为根本没有描述字段。
例如,如果我尝试在如下所示的已知路径上使用命令
jq '.known.level.description //= "DUMMY DESCRIPTION"' ........
它无法跳过不存在的字段,例如.a.b [2] .description;并且可以肯定,它仅适用于JSON中的已知位置。如果我尝试执行递归搜索,例如:
jq '.. | .description? //= "DUMMY DESCRIPTION"' ........
它似乎无法在数组上正常工作。
在这种情况下遍历整个JSON的正确方法是什么?谢谢!
答案 0 :(得分:1)
在这种情况下遍历整个JSON的正确方法是什么?
答案是walk
!
如果您的jq还没有walk/1
,则可以轻松地对其进行Google搜索(jq“ def walk”),然后在使用它之前包含其def,例如如下:
walk(if type == "object" and has("description") and .description == null
then .description = "DUMMY DESCRIPTION"
else . end)
答案 1 :(得分:0)
您可以考虑的一种选择是使用流。您将获得输入中每个项目的路径和值。这样,您可以查找名称为"description"
的名称/值对,并更新值。
$ jq --arg replacement "DUMMY DESCRIPTION" '
fromstream(tostream | if length == 2 and .[0][-1] == "description"
then .[1] |= (. // $replacement)
else .
end)
' input.json