假设我有一个如下所示的 JSON:
{
"key1": {
"keyA": "1",
"keyB": "null",
"keyC": "null"
},
"key2": {
"keyA": "null",
"keyB": "3",
"keyC": "null"
}
}
Run Code Online (Sandbox Code Playgroud)
我想找到一种方法来排除所有具有null
JSON值的键。所以结果如下:
{
"key1": {
"keyA": "1"
},
"key2": {
"keyB": "3"
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用它们的名字排除特定的键jq
,例如cat myjson.json | jq 'del(.[]|.keyA)'
,这将删除我keyA
在 json 中的所有键,但我想根据它们的值排除这些键......如何"null"
使用排除所有具有值的键jq
?
del(..|select(. == "null"))
Run Code Online (Sandbox Code Playgroud)
这使用递归下降运算符..
和select
函数来查找对象中任何位置的所有位置,其值等于"null"
并将它们赋予del
。select
计算布尔表达式以决定是否包含特定值,同时..
将树中的每个值都提供给它,并del
接受任何产生位置的表达式,这是这样做的。(演示)
您可以使用该path
函数来检查它发现了什么:
path(..|select(. == "null"))
Run Code Online (Sandbox Code Playgroud)
并调试它认为您首先要删除的内容。该输出是按键阵列遵循递归为达到值,所以数组中的最后一个项目是,实际上被删除的关键。
您还可以|= empty
在 jq 1.6 及更高版本中使用更新分配(它在早期版本中默默地失败)。您可能会或可能不会发现这个清晰的:(..|select(. == "null")) |= empty
(演示)删除那些相同的密钥。
如果您的值是 true null
s,而不是 string "null"
,则可以使用nulls
内置函数代替整个select
: del(..|nulls)
。
如果你的价值观是真正的空和你使用JQ 1.5(当前版本中许多发行),你需要使用recurse(.[]?; true)
的地方..
。这是因为空值被明确排除在外..
(因为它定义为recurse
,定义为 recurse(.[]?)
,定义为recurse(.[]?; . != null)
)。这种行为在 1.6 中变成了上面的(更有用的)行为,尽管文档没有改变,这似乎是一个文档错误。