我有一个巨大的JSON文件,其中包含如下记录:
{"callsign":"abc","kruxSegmentIds":{"0":"q2d9nn1qv","1":"rle4kfgsf"},"liveFlag":"Y"}}
我需要以如下方式替换嵌套JSON密钥“ kruxSegmentIds”内的密钥:0变为“零”,而1变为“一个”,如下所示:
{"callsign":"abc","kruxSegmentIds":{"zero":"q2d9nn1qv","one":"rle4kfgsf"},"liveFlag":"Y"}}
使用sed是否可能?我不想编写脚本,因为文件很大,可能不适合内存。
非常感谢您的帮助/支持。
答案 0 :(得分:2)
从问题描述(以及提议的awk解决方案已被接受的事实)来看,很明显,尽管文件本身很大,但是每个JSON文档相对较小,或者至少足够小以适合内存。如果确实如此,那么使用jq的简单解决方案将具有与sed
或awk
解决方案相似的性能特征,但没有潜在的复杂性。因此,这是一个解决方案:
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中获取其定义