首页 > 解决方案 > 如何使用 jq 将数组拆分为块?

问题描述

我有一个非常大的 JSON 文件,其中包含一个数组。是否可以jq将此数组拆分为几个固定大小的较小数组?假设我的输入是这样的:[1,2,3,4,5,6,7,8,9,10],我想把它分成 3 个元素的长块。所需的输出jq将是:

[1,2,3]
[4,5,6]
[7,8,9]
[10]

实际上,我的输入数组有近 300 万个元素,都是 UUID。

标签: arraysjsonshelljqmemory-efficient

解决方案


有一个(未记录的)内置_nwise函数,满足功能要求:

$ jq -nc '[1,2,3,4,5,6,7,8,9,10] | _nwise(3)'

[1,2,3]
[4,5,6]
[7,8,9]
[10]

还:

$ jq -nc '_nwise([1,2,3,4,5,6,7,8,9,10];3)' 
[1,2,3]
[4,5,6]
[7,8,9]
[10]

顺便说一句,_nwise可以用于数组和字符串。

(我相信它是无证的,因为对合适的名称存在一些疑问。)

TCO 版本

不幸的是,内置版本被粗心地定义,并且对于大型数组表现不佳。这是一个优化版本(它应该与非递归版本一样高效):

def nwise($n):
 def _nwise:
   if length <= $n then . else .[0:$n] , (.[$n:]|_nwise) end;
 _nwise;

对于大小为 300 万的数组,这是相当高效的:在旧 Mac 上为 3.91s,最大驻留大小为 162746368。

请注意,此版本(使用尾调用优化递归)实际上比本页其他地方显示的nwise/2using版本更快。foreach


推荐阅读