# 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条答案
按热度按时间jaql4c8m1#
jq的流式解析器(使用--stream选项调用)通常可以处理非常非常大的文件(甚至在满足某些条件的情况下处理任意大的文件),但是它通常非常慢并且通常相当麻烦。
在实践中,我发现像jstream和/或我自己的jm这样的工具与jq结合在一起处理巨大的文件时非常好用,当这样使用时,它们都非常容易使用,尽管安装可能有点麻烦。
不幸的是,如果您对JSON文件的内容一无所知,只知道
jq empty
耗时太长或失败,那么据我所知,没有CLI工具可以自动生成有用的模式。然而,查看文件的前几个字节通常会提供足够的信息。或者,您可以从jm count
开始,给予顶层对象的计数。如果顶级键是JSON对象,jm -s | jq 'keys[]'
将给予顶级键的列表。下面是一个例子,假设我们已经确定ginormous.json文件的大小主要是因为它包含了一个很长的顶级数组,然后假设schema.jq(本页其他地方已经提到过)在pwd中,那么您有希望通过运行以下命令找到一个信息丰富的模式:
另请参见jq to recursively profile JSON object,了解更简单的模式推理引擎。
cnh2zyt32#
确定包含单个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程序中添加以下代码:krcsximq3#
我在这里发布了一个相关的问题:Difference between slurp, null input, and inputs filter
如果您的文件很大,但文件中的文档并不是很大(只是许多小文档),
jq -n 'inputs'
可以帮助您开始:下面是一个示例(包含一个小文件):
如果您只有一个数千兆字节大小或有数百万个键的顶级对象,那么这种方法就不起作用。