【发布时间】:2019-07-28 03:18:36
【问题描述】:
我有一个由一棵巨大的 JSON 树组成的数据库转储。 我想提取一个特定的子树,它比其他子树小得多,具有已知的特定键。
{ "key1": { subtree1... }, "key2": { subtree2... }, ... }
如何使用流 jq 提取 subtreeN?
【问题讨论】:
我有一个由一棵巨大的 JSON 树组成的数据库转储。 我想提取一个特定的子树,它比其他子树小得多,具有已知的特定键。
{ "key1": { subtree1... }, "key2": { subtree2... }, ... }
如何使用流 jq 提取 subtreeN?
【问题讨论】:
在下文中,我们假设 $key 持有感兴趣的密钥。
这里提高效率的关键是在--stream 选项产生的流处理完成$key 键的处理后终止。
为此,我们可以定义一个辅助函数,如下所示。请注意,它使用inputs,因此 jq 的调用必须使用 -n 命令行选项。
# break out early
def filter($key):
label $out
| foreach inputs as $in ( null;
if . == null
then if $in[0][0] == $key then $in
else empty
end
elif $in[0][0] != $key then break $out
else $in
end;
select(length==2) );
所需键值对的重构现在可以如下完成:
reduce filter($key) as $in ({};
setpath($in[0]; $in[1]) )
{
"key1": {
"subtree1": {
"a": {"aa":[1,2,3]}
}
},
"key2": {
"subtree2": {
"b1": {"bb":[11,12,13]},
"b2": {"bb":[11,12,13]}
}
},
"key3": {
"subtree3": {
"c": {"cc":[21,22,23]}
}
}
}
jq -n -c --arg key "key2" --stream -f extract.jq input.json
{"key2":{"subtree2":{"b1":{"bb":[11,12,13]},"b2":{"bb":[11,12,13]}}}}
【讨论】:
atomize 函数的解决方案要好得多。