jq通过流式传输从巨大(10GB)JSON文件中提取一个子树

bogh5gae  于 2023-03-09  发布在  其他
关注(0)|答案(2)|浏览(119)

我有一个数据库转储文件,它由一个巨大的JSON树组成,我想提取一个特定的子树,它比其他子树小得多,并具有一个已知的特定键。

{ "key1": { subtree1... }, "key2": { subtree2... }, ... }

如何使用流jq提取subtreeN

c3frrgcw

c3frrgcw1#

在下面,我们假设$key持有我们感兴趣的键。
这里效率的关键是在--stream选项产生的流处理完成$key键后终止,为此,我们可以定义一个helper函数,注意它使用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]) )

示例输入. json

{
  "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]}}}}
z31licg0

z31licg02#

下面是一个使用jq的--stream选项的简单一行程序:

jq —-stream 'first(fromstream(select(.[0][0]=="key2"), [["key2"]]))'

相关问题