在从行分隔的JSON中提取的字段上使用unix工具(例如sort)

时间:2015-08-26 02:46:49

标签: json unix twitter jq

jq这样的工具对从line-delimited JSON声明性地提取和过滤内容非常有用。但是,它似乎需要将所有对象放入内存以执行排序等操作,通常利用现有的* NIX工具处理来自JSON 的一个或多个字段同时保留原始JSON blob可能很有用/ em>的

例如,给定Twitter API中以行分隔的JSON,我想按时间戳排序推文JSON blob。这可以通过将Twitter日期格式转换为ISO8601(其词典和时间顺序相同),在JSON推文blob前加上该日期,将流传递到GNU sort和{{}来实现。 1}}删除前置日期。

虽然可以使用cutmkfifo来实现这一目标,但我希望通过paste使用更简洁的解决方案。

2 个答案:

答案 0 :(得分:3)

可以使用以下命令对Twitter JSON blob流进行排序:

jq

对于每个JSON blob,jq -r '(.created_at | strptime("%a %b %d %H:%M:%S +0000 %Y") | todate) + "\t" + tostring' | sort -k1,1 | cut -f2 命令解析“created_at”字段并输出ISO8601日期,后跟选项卡,后跟原始JSON(不包含制表符或换行符)。 jq / --raw-output标志确保这不是JSON编码,而是输出为原始文本。然后按GNU -r或等效项对流进行排序,单独的JSON blob由sort重新调整。

答案 1 :(得分:1)

jq可以很容易地与其他命令行工具一起使用,这确实是jq的优势之一,但是不再需要使用“slurp”选项(--slurp或-s)来完成诸如描述的那个(即,减少JSON实体的输入流)。关键是jq版本1.5中的新“输入”过滤器。

为了说明如何使用“输入”来避免将输入文件读入内存,请考虑查找JSON实体文件的最大值的任务。这是一个解决方案:

$ jq -n 'reduce inputs as $i (null; [., $i] | max)'

请注意,此处需要-n选项。

总之,使用jq 1.5,可以通过一次读取一个JSON实体流(例如可能包含在文件中)来轻松处理,无论每个输入实体是否在一条线上。关键是使用“输入”和“-n”选项。

同样,非常大的文本文件现在也可以在一次一行的基础上处理,同时仍然能够执行一些缩减操作;这可以使用-R选项和-n和输入完成。