# Output: a stream of the distinct `tostring` values of the items in the stream
def uniques(stream):
foreach (stream|tostring) as $s ({};
if .[$s] then .emit = false else .emit = true | .item = $s | .[$s]=true end;
if .emit then .item else empty end );
def spaths($depth):
inputs
| select(length==1)[0][0:$depth]
| map(if type == "number" then 0 else . end);
uniques(spaths($depth))
3条答案
按热度按时间bxgwgixi1#
jq的流解析器(使用--stream选项调用)通常可以处理非常非常大的文件(如果满足某些条件,甚至可以处理任意大的文件),但是它通常非常慢,而且通常非常麻烦。
在实践中,我发现像jstream和/或我自己的jm这样的工具在处理ginormous文件时与jq配合使用非常好,当以这种方式使用时,它们都非常容易使用,尽管安装可能有点麻烦。
不幸的是,如果您对JSON文件的内容一无所知,只知道
jq empty
花费的时间太长或失败,那么据我所知,没有一个CLI工具可以自动生成有用的模式。然而,查看文件的前几个字节通常可以提供足够的信息。或者,您可以从jm count
开始,给予顶层对象的计数,如果顶级键是JSON对象,jm -s | jq 'keys[]'
将给予顶级键的列表。下面是一个例子。假设我们已经确定文件ginormous.json的大小主要是因为它包含了一个非常长的顶级数组。然后假设schema.jq(在本页的其他地方已经提到过)在pwd中,你有希望通过运行以下命令找到一个信息模式:
o0lyfsai2#
确定包含单个JSON实体的超大文件的结构的一种通用方法是运行以下查询:
其中
structural_paths.jq
包含:请注意,输出中的“0”表示在相应的位置上至少有一个有效的数组索引,而不是“0”实际上是该位置上的有效索引。
还要注意,对于非常大的文件,使用jq --stream处理整个文件可能会非常慢。
示例:
给定
{"a": {"b": [0,1, {"c":2}]}}
,上述咒语的结果将是:顶层结构
如果您只想了解有关顶层结构的更多信息,您可以将上面的jq程序简化为:
指定深度的结构
如果命令行
sort
失败,则您可能希望通过将路径仅考虑到特定深度来限制路径的数量。如果深度不是太大,那么希望您的命令行
sort
能够管理;如果不是,那么使用命令行uniq
至少会稍微调整输出。更好的选择可能是在jq中定义
unique(stream)
,然后使用它,如下所示:jq的适当调用如下所示:
除了避免排序的开销外,使用
uniques/1
还将保留原始JSON中路径的顺序。“JSON指针”指针
如果你想将数组路径表达式转换为“JSON指针”字符串(例如,用于
jm
或jstream
),只需将以下代码附加到相关的jq程序中:v1uwarro3#
我在这里发布了一个相关的问题:Difference between slurp, null input, and inputs filter
如果您的文件很大,但文件中的文档并不是很大(只是许多小文档),
jq -n 'inputs'
可以帮助您开始:下面是一个示例(带有一个小文件):
如果您有一个数GB大或有数百万个键的单个顶级对象,则这种方法 * 不 * 起作用。