查找并替换嵌套的JSON密钥

时间:2018-10-08 03:54:07

标签: json jq

我有一个巨大的JSON文件,其中包含如下记录:

{"callsign":"abc","kruxSegmentIds":{"0":"q2d9nn1qv","1":"rle4kfgsf"},"liveFlag":"Y"}}

我需要以如下方式替换嵌套JSON密钥“ kruxSegmentIds”内的密钥:0变为“零”,而1变为“一个”,如下所示:

{"callsign":"abc","kruxSegmentIds":{"zero":"q2d9nn1qv","one":"rle4kfgsf"},"liveFlag":"Y"}}

使用sed是否可能?我不想编写脚本,因为文件很大,可能不适合内存。

非常感谢您的帮助/支持。

1 个答案:

答案 0 :(得分:2)

从问题描述(以及提议的awk解决方案已被接受的事实)来看,很明显,尽管文件本身很大,但是每个JSON文档相对较小,或者至少足够小以适合内存。如果确实如此,那么使用jq的简单解决方案将具有与sedawk解决方案相似的性能特征,但没有潜在的复杂性。因此,这是一个解决方案:

jq '.kruxSegmentIds |= with_entries(.key |= if .=="0" then "zero" elif .=="1" then "one" else . end)'

如果jq empty hugefile由于文件大小而失败,则jq可能仍然有用,因为它是专门为此类情况设计的流解析器。

变化

在评论中,OP发布了另一个示例,因此定义用于执行键到键转换的过滤器可能很有用:

def twiddle:
  with_entries(.key |= if .=="0" then "zero" elif .=="1" then "one" else . end);

以此解决原始问题的方法是:

 .kruxSegmentIds |= twiddle

该变体的解决方案是:

(.users.L3AVIcqaDpZxLf6ispK.kruxSegmentIds) |= twiddle 

进一步概括,如果任务是对所有对象进行转换,无论它们发生在哪里,解决方案都是:

walk(if type == "object" then twiddle else . end)

如果您的jq没有预先定义的walk,则可以从https://raw.githubusercontent.com/stedolan/jq/master/src/builtin.jq中获取其定义