【问题标题】:How to transform a JSON array to a JSON map: one specific array element attribute value becomes the key of each map如何将 JSON 数组转换为 JSON 映射:一个特定的数组元素属性值成为每个映射的键
【发布时间】:2017-04-23 02:50:42
【问题描述】:

我想转换 Node.js pm2 进程列表 (pm2 jlist > pm2-jlist.json) 的 JSON,以便以稍微不同的格式将其提供给 collectd(遥测)。

输入 JSON:

[
    {
        "pid": 1419,
        "name": "myapp",
        "pm_id": 0,
        "monit": {
            "memory": 13795328,
            "cpu": 0
        }
    },
    {
        "pid": 1425,
        "name": "calendar-viewer",
        "pm_id": 1,
        "monit": {
            "memory": 22761472,
            "cpu": 0
        }
    }
]

预期输出:

{
    "myapp": {
        "cpu": 0,
        "memory": 14548992,
        "pid": 1419
    },
    "calendar-viewer": {
        "cpu": 0,
        "memory": 16957440,
        "pid": 1425
    }
}

所以我想将 Input JSON 数组的每个数组元素转换为 JSON 映射元素如下:

  1. 键为“name”的属性值被提升为该地图元素的键。

  2. “monit”子树下的属性合并在该映射的键下(这部分已经工作)。

如果数组包含多个元素,我将无法获得所需的输出。

尝试#1:这几乎是正确的,但输出包含 2 个 json 对象(无效语法)而不是 1 个 json 对象...

cat pm2-jlist.json | jq '.[] | {(.name): {pid: .pid,cpu: .monit.cpu, memory: .monit.memory}}'

{
  "myapp": {
    "pid": 1419,
    "cpu": 0,
    "memory": 14548992
  }
}
{
  "calendar-viewer": {
    "pid": 1425,
    "cpu": 0,
    "memory": 16957440
  }
}

尝试#2:我只能过滤掉 1 个 json 对象,但我想要 1 个 json 对象中的所有项目...

cat pm2-jlist.json | jq '.[] | select(.name == "calendar-viewer")| {(.name): {pid: .pid, cpu: .monit.cpu, memory: .monit.memory}}'

{
  "calendar-viewer": {
    "pid": 1425,
    "cpu": 0,
    "memory": 16957440
  }
}

感谢您的宝贵时间。

【问题讨论】:

    标签: json dictionary jq


    【解决方案1】:

    根据您的输入,过滤器:

    map( { (.name): (.monit + {pid} ) } ) | add
    

    产生:

    {
      "myapp": {
        "memory": 13795328,
        "cpu": 0,
        "pid": 1419
      },
      "calendar-viewer": {
        "memory": 22761472,
        "cpu": 0,
        "pid": 1425
      }
    }
    

    【讨论】:

    • 完美运行。感谢您帮助使用 map() 并添加
    【解决方案2】:

    我不是 jq 专家,但从概念上讲,您所追求的是 reduce

    鉴于我期望事情如何运作,这是我的最佳猜测......

    reduce .[] as $item ({}; .[$item.name] = {"cpu" : $item.monit.cpu, "memory" : $item.monit.memory, "pid" : $item.pid})
    

    对于它的价值,jqplay.org 为您的输入和上面的过滤器生成以下输出:

    {
      "myapp": {
        "cpu": 0,
        "memory": 13795328,
        "pid": 1419
      },
      "calendar-viewer": {
        "cpu": 0,
        "memory": 22761472,
        "pid": 1425
      }
    }
    

    【讨论】:

    • 这很好用。我更喜欢 的答案,因为它更简单。我认为“峰值”是 jq 的作者之一,因为他大多提供最佳答案
    猜你喜欢
    • 2017-06-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多