如何用jq计算json中嵌套标量前面的键数

ulydmbyx  于 2023-10-21  发布在  其他
关注(0)|答案(1)|浏览(131)

我有深度嵌套的jsons,我想用jq来计算标量前面有多少个键。这里有一个非常简单的例子

{
    "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,
  14,
  14,
  14,
  14,
  14,
  14,
  14
]

这样

"one.two.three.[].four.[].five.[].six.[].sevenA.eightA.[].nineA",
  "one.two.three.[].four.[].five.[].six.[].sevenA.eightA.[].nineB",
  "one.two.three.[].four.[].five.[].six.[].sevenA.eightA.[].nineC",
  "one.two.three.[].four.[].five.[].six.[].sevenA.eightA.[].nineD",
  "one.two.three.[].four.[].five.[].six.[].sevenB.eightB.[].nineE",
  "one.two.three.[].four.[].five.[].six.[].sevenB.eightB.[].nineF",
  "one.two.three.[].four.[].five.[].six.[].sevenB.eightB.[].nineG",
  "one.two.three.[].four.[].five.[].six.[].sevenB.eightB.[].nineH"

所以我得到了上面例子的结果14。
但我只想这样数钥匙。

".one.two.three[].four[].five[].six[].sevenB.eightB[].nineE"
".one.two.three[].four[].five[].six[].sevenB.eightB[].nineF"
".one.two.three[].four[].five[].six[].sevenB.eightB[].nineG"
".one.two.three[].four[].five[].six[].sevenB.eightB[].nineH"
".one.two.three[].four[].five[].six[].sevenB.eightB[].nineE"
".one.two.three[].four[].five[].six[].sevenB.eightB[].nineF"
".one.two.three[].four[].five[].six[].sevenB.eightB[].nineG"
".one.two.three[].four[].five[].six[].sevenB.eightB[].nineH"

标量前面有9个键,标量的键值对前面有8个键。
谁能帮帮我怎么用jq做这个?

eqoofvh9

eqoofvh91#

要生成键深度流,您可以这样写:

jq 'paths(scalars) | map(strings) | length' input.json

或者考虑到潜在的效率增强,您可以使用通用的面向流的count/1

def count(stream):
  reduce stream as $_ (0; .+1);

paths(scalars) | count(.[] | strings)

或者使用通用的面向流的“max”函数来计算最大键深度:

def count(stream):
  reduce stream as $_ (0; .+1);

# max(empty) is empty
def max(stream):
  reduce (stream | [.]) as $x (null;
    if . == null or $x > . then $x else . end )
  | if . == null then empty else .[0] end;

max(paths(scalars) | count(.[] | strings))

相关问题