如何将 JSON 数组转换为 JSON 映射:一个特定的数组元素属性值成为每个映射的键
How to transform a JSON array to a JSON map: one specific array element attribute value becomes the key of each map
我想转换 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 map 元素,如下所示:
具有键 "name" 的属性值被提升为该地图元素的键。
"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
}
}
感谢您的宝贵时间。
我不是 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
}
}
根据您的输入,过滤器:
map( { (.name): (.monit + {pid} ) } ) | add
产生:
{
"myapp": {
"memory": 13795328,
"cpu": 0,
"pid": 1419
},
"calendar-viewer": {
"memory": 22761472,
"cpu": 0,
"pid": 1425
}
}
我想转换 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 map 元素,如下所示:
具有键 "name" 的属性值被提升为该地图元素的键。
"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
}
}
感谢您的宝贵时间。
我不是 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
}
}
根据您的输入,过滤器:
map( { (.name): (.monit + {pid} ) } ) | add
产生:
{
"myapp": {
"memory": 13795328,
"cpu": 0,
"pid": 1419
},
"calendar-viewer": {
"memory": 22761472,
"cpu": 0,
"pid": 1425
}
}