【发布时间】:2017-09-06 00:31:49
【问题描述】:
我想使用 jq 删除 JSON“对象”(我通常使用该术语来指代数组或字典)中的所有字典,
a) 包含一个名为“delete_me”的键,并且 b) 键“delete_me”满足某个预定条件(空、非零、真等)的地方
基本上,我要实现的逻辑是:遍历输入,并且在每个节点处,如果该节点不是数组或对象,则保留它并继续前进,否则,保留它但从中删除任何子节点是条件 a) 或 b) 失败的字典。
有什么建议吗?
示例输入:
{
"a": { "foo": "bar" },
"b": {
"i": {
"A": {
"i": [
{
"foo": {},
"bar": {
"delete_if_this_is_null": false,
"an_array": [],
"another_array": [
{
"delete_if_this_is_null": null,
"foo": "bar"
}
],
"etc": ""
},
"foo2": "s"
},
{
"foo": {
"an_array": [
{
"delete_if_this_is_null": "ok",
"foo":"bar",
"another_object": { "a":1 }
},
{
"delete_if_this_is_null": null,
"foo2":"bar2",
"another_object": { "a":1 },
"name": null
}
],
"an_object": {
"delete_if_this_is_null":null,
"foo3":"bar3"
}
},
"zero": 0,
"b": "b"
}
]
}
}
}
}
如果“delete_me”键为delete_if_this_is_null且预定条件为delete_if_this_is_null == null,则应该让步:
{
"a": { "foo": "bar" },
"b": {
"i": {
"A": {
"i": [
{
"foo": {},
"bar": {
"delete_if_this_is_null": false,
"an_array": [],
"another_array": [],
"etc": ""
},
"foo2": "s"
},
{
"foo": {
"an_array": [
{
"delete_if_this_is_null": "ok",
"foo":"bar",
"another_object": { "a":1 }
}
]
},
"zero": 0,
"b": "b"
}
]
}
}
}
}
更新:这是解决方案:假设输入在文件'input.json'中:
jq 'def walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;
def mapper(f):
if type == "array" then map(f)
elif type == "object" then
. as $in
| reduce keys[] as $key
({};
[$in[$key] | f ] as $value
| if $value | length == 0 then .
else . + {($key): $value[0]} end)
else .
end;
walk( mapper(select((type == "object" and .delete_if_this_is_null == null) | not)) )' < input.json
【问题讨论】:
-
请编辑您的问题以包含输入 JSON 和所需输出的示例。
-
根据您的定义,数组有一个名为“delete_me”的“键”是什么意思?数组具有整数索引。这没有意义。
-
@Jeff,我说我想删除可以是数组或字典的对象中的“所有字典”。我没有说我会删除一个数组。因此输入对象(或其中的任何节点)可以是包含满足条件 a) 和 b) 的字典的数组,在这种情况下,我想从数组中删除该元素。这怎么没有意义?
-
@Jordan,将在今晚晚些时候发布。我当前的数据结构是专有的,所以我必须重新创建通用数据才能发布。
-
我想更相关的问题是,您所说的“我通常使用该术语来指代数组或字典”是什么意思,您指的是什么?你提出问题的方式有点令人困惑。