【问题标题】:How to flatten JSON with nested structure before passing to @csv filter如何在传递给@csv过滤器之前用嵌套结构展平JSON
【发布时间】:2024-09-12 06:40:01
【问题描述】:

我正在尝试解析一些作为 AWS CLI 命令输出的 JSON 以显示快照。我想将此数据加载到电子表格中,以便能够对其进行过滤、分组和审核。

我一直困惑于如何将嵌套的标签数组展平到父对象中,以便可以将中间对象传递给 @csv 过滤器。

示例如下:

初始输入 JSON:

{
  "Snapshots": [
    {
      "SnapshotId": "snap-fff",
      "StartTime": "2014-04-01T06:00:13.000Z",
      "VolumeId": "vol-fff",
      "VolumeSize": 50,
      "Description": "desc1",
      "Tags": [
        {
          "Value": "/dev/sdf",
          "Key": "device"
        },
        {
          "Value": "a name",
          "Key": "Name"
        },
        {
          "Value": "Internal",
          "Key": "Customer"
        },
        {
          "Value": "Demo",
          "Key": "Environment"
        },
        {
          "Value": "Brand 1",
          "Key": "Branding"
        },
        {
          "Value": "i-fff",
          "Key": "instance_id"
        }
      ]
    },
    {
      "SnapshotId": "snap-ccc",
      "StartTime": "2014-07-01T05:59:14.000Z",
      "VolumeId": "vol-ccc",
      "VolumeSize": 8,
      "Description": "B Desc",
      "Tags": [
        {
          "Value": "/dev/sda1",
          "Key": "device"
        },
        {
          "Value": "External",
          "Key": "Customer"
        },
        {
          "Value": "Production",
          "Key": "Environment"
        },
        {
          "Value": "i-ccc",
          "Key": "instance_id"
        },
        {
          "Value": "B Brand",
          "Key": "Branding"
        },
        {
          "Value": "B Name",
          "Key": "Name"
        },
        {
          "Value": "AnotherValue",
          "Key": "AnotherKey"
        }
      ]
    }
  ]
}

所需的中级:

[
  {
    "SnapshotId": "snap-fff",
    "StartTime": "2014-04-01T06:00:13.000Z",
    "VolumeId": "vol-fff",
    "VolumeSize": 50,
    "Description": "desc1",
    "device": "/dev/sdf",
    "Name": "a name",
    "Customer": "Internal",
    "Environment": "Demo",
    "Branding": "Brand 1",
    "instance_id": "i-fff",
  }
  {
    "SnapshotId": "snap-ccc",
    "StartTime": "2014-07-01T05:59:14.000Z",
    "VolumeId": "vol-ccc",
    "VolumeSize": 8,
    "Description": "B Desc",
    "device": "/dev/sda1",
    "Customer": "External",
    "Environment": "Production",
    "instance_id": "i-ccc",
    "Branding": "B Brand",
    "Name": "B Name",
    "AnotherKey": "AnotherValue",
  }
]

最终输出:

"SnapshotId","StartTime","VolumeId","VolumeSize","Description","device","Name","Customer","Environment","Branding","instance_id","AnotherKey"
"snap-fff","2014-04-01T06:00:13.000Z","vol-fff",50,"desc1","/dev/sdf","a name","Internal","Demo","Brand 1","i-fff",""
"snap-ccc","2014-07-01T05:59:14.000Z","vol-ccc",8,"B Desc","/dev/sda1","External","Production","i-ccc","B Brand","B Name","AnotherValue"

【问题讨论】:

    标签: nested jq flatten


    【解决方案1】:

    以下 jq 过滤器产生请求的中间输出:

    .Snapshots[] | (. + (.Tags|from_entries)) | del(.Tags)
    

    解释:from_entries 将键值对象数组转换为具有给定键值对的对象。这被添加到目标对象,最后“标签”键被删除。

    如果“目标”对象的键也出现在“标签”数组中,则上述过滤器将优先选择“标签”数组中的值。因此,您可能希望更改“+”操作数的顺序,或以其他方式解决冲突。

    【讨论】:

    • 伙计..我在这个解决方案周围跳舞,但我从来没有去过那里。非常感谢!