首页 > 解决方案 > jq - 如何遍历具有不同名称的嵌套键?

问题描述

我有以下格式的数据。键在元素之间是唯一的。

{
  "backend1": {
    "product1": {
      "subservice1": {
        "env1": {
          "KMS": "0.21",
          "DynamoDB": "235.91",
          "ElastiCache": "108.85",
          "Elastic Load Balancing": "324.29"
        },
        "env2": {
          "KMS": "0.21",
          "Elastic Load Balancing": "3.78"
        }
      }
    }
  },
  "backend2": {
    "product2": {
      "subservice2": {
        "env1": {
          "KMS": "0.21",
          "ElastiCache": "108.85",
          "Elastic Load Balancing": "41.18"
        },
        "env2": {
          "KMS": "0.21",
          "Elastic Load Balancing": "3.78"
        }
      }
    }
  }
}

我想遍历键并将 JSON 转换为 Prometheus 度量格式。

aws_cost{env="env1",aws_service="KMS",product="product1",backend="backend1",subservice="subservice1"} 0.21
aws_cost{env="env1",aws_service="DynamoDB",product="product1",backend="backend1",subservice="subservice1"} 235.91
aws_cost{env="env1",aws_service="ElastiCache",product="product1",backend="backend1",subservice="subservice1"} 108.85
.....

我发现你可以通过 using 获取不同索引处的键,.[] | .[] | .[] | .[]但我不知道如何使用嵌套的 for 循环来生成上面的数据。我对其他解决方案持开放态度。

标签: jsonjq

解决方案


由于对象的键确定不同的值,因此如果您将值流式传输进来,您可以很好地做到这一点。然后您只需要解析路径的各个部分并构建结果。

流式传输,解析,然后输出。

$ jq --stream -r '
select(length == 2) as [[$backend, $product, $subservice, $env, $aws_service], $value]
  | {$env, $aws_service, $product, $backend, $subservice}
  | "aws_cost{\([to_entries[] | "\(.key)=\(.value|tojson)"] | join(","))} \($value)"
' input.json
aws_cost{env="env1",aws_service="KMS",product="product1",backend="backend1",subservice="subservice1"} 0.21
aws_cost{env="env1",aws_service="DynamoDB",product="product1",backend="backend1",subservice="subservice1"} 235.91
aws_cost{env="env1",aws_service="ElastiCache",product="product1",backend="backend1",subservice="subservice1"} 108.85
aws_cost{env="env1",aws_service="Elastic Load Balancing",product="product1",backend="backend1",subservice="subservice1"} 324.29
aws_cost{env="env2",aws_service="KMS",product="product1",backend="backend1",subservice="subservice1"} 0.21
aws_cost{env="env2",aws_service="Elastic Load Balancing",product="product1",backend="backend1",subservice="subservice1"} 3.78
aws_cost{env="env1",aws_service="KMS",product="product2",backend="backend2",subservice="subservice2"} 0.21
aws_cost{env="env1",aws_service="ElastiCache",product="product2",backend="backend2",subservice="subservice2"} 108.85
aws_cost{env="env1",aws_service="Elastic Load Balancing",product="product2",backend="backend2",subservice="subservice2"} 41.18
aws_cost{env="env2",aws_service="KMS",product="product2",backend="backend2",subservice="subservice2"} 0.21
aws_cost{env="env2",aws_service="Elastic Load Balancing",product="product2",backend="backend2",subservice="subservice2"} 3.78

推荐阅读