jq,拆分数组的巨大json并保存到以值命名的文件中

时间:2019-05-16 11:01:51

标签: json awk split jq

我有一个包含对象数组的json,每个对象在以下位置均包含唯一值:

"id":"value"

我遵循了other answer,我可以使用jq和awk将整个文档分成多个文件

jq -c ".[]" big.json | gawk '{print > "doc00" NR ".json";}'

这样,输出文件将按顺序命名。
我如何使用id值命名文件?

3 个答案:

答案 0 :(得分:1)

对于数组中的每个元素,将id和元素本身打印在两行中,因此您可以从奇数行中获取id并将偶数行打印到以id命名的文件中。

jq -cr '.[] | .id, .' big.json | awk 'NR%2{f=$0".json";next} {print >f;close(f)}'

答案 1 :(得分:1)

使用.id作为文件名的一部分充满了风险。

首先,存在嵌入换行符的潜在问题。

第二,存在“保留”字符的问题,特别是“ /”。

第三,Windows对文件名有很多限制-参见例如https://gist.github.com/doctaphred/d01d05291546186941e1b7ddc02034d3

此外,如果使用jq的-r选项(如本页上的其他帖子所建议),则"1"1的.id值都将映射到1,如果在awk中使用“>”,将导致数据丢失。

因此,这里有一个解决方案,说明了如何在OS X或* ix环境中实现安全性,并为实现Windows的安全解决方案大有帮助:

jq -c '.[]
       | (.id | if type == "number" then .
                else tostring | gsub("[^A-Za-z0-9-_]";"+") end), .' |
awk '
  function fn(s) { sub(/^\"/,"",s); sub(/\"$/,"",s); return s ".json"; }
  NR%2{f=fn($0); next} 
  {print >> f; close(f);}
' 

请特别注意使用“ >>”以避免文件名冲突时丢失数据。

答案 2 :(得分:0)

由于问题描述表明输入数组很大,因此可能值得考虑使用jq的流解析器。通常,如果输入的JSON太大而无法读入内存,或者如果减少计算机内存需求是一个重要目标,那么这将是适当的。

简而言之,不是以通常的方式调用jq,而是添加了-n和--stream命令行选项,并用以下方式替换了初始的.[]

fromstream(1|truncate_stream(inputs))

然后可以按照本页其他地方的说明进行拆分。