如何用jq统计嵌套JSON中标量前的键数量(排除数组索引)
问题:统计JSON路径中仅键的数量
我有一个深度嵌套的JSON结构,想要统计标量值前方的键的数量(排除数组索引)。简化示例JSON如下:
{ "one": { "two": { "three": [ { "four": [ { "five": [ { "six": [ { "sevenA": { "eightA": [ { "nineA": "Blub" }, { "nineB": "def" }, { "nineC": "foo" }, { "nineD": 22 } ] } }, { "sevenB": { "eightB": [ { "nineE": "Bla" }, { "nineF": "int" }, { "nineG": "s" }, { "nineH": 60 } ] } } ] } ] } ] } ] } } }
我用命令 jq '[paths(scalars)] | map(length)' 得到的是路径中键和数组索引的总数量(结果都是14),但我需要仅统计路径中的键:
- 如果包含标量自身的键(比如
nineA这类),数量应为9 - 如果只统计标量键值对前方的键(即排除
nineA这类),数量应为8
解决方案
1. 统计包含标量自身键的数量(结果为9)
通过过滤路径中类型为字符串的元素(数组索引是数字,键是字符串),统计这类元素的数量:
jq '[paths(scalars) | map(type == "string") | add]'
执行后会得到8个9,符合需求。
2. 统计标量前方的键数量(结果为8)
如果要排除标量自身的键,只需去掉路径的最后一个元素后再统计:
jq '[paths(scalars)[:-1] | map(type == "string") | add]'
执行后会得到8个8,对应标量键值对前方的键数量。
原理说明
paths(scalars):生成所有指向标量值的路径数组,每个路径由键(字符串)和数组索引(数字)组成map(type == "string"):判断路径中每个元素是否为字符串(即是否是键),生成布尔值数组add:将布尔值数组求和(true等价于1,false等价于0),得到键的总数量[:-1]:截取路径的前n-1个元素,去掉最后一个元素(即标量自身的键)
内容的提问来源于stack exchange,提问作者john-soda
相关产品推荐
相关产品推荐

