You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用jq提取嵌套JSON指定键值对为顶级字段,缺失值设为null?

问题:解析嵌套JSON为顶级字段并处理缺失值

需要查询JSON数据,将嵌套的键值对解析为输出中的顶级字段;当部分输入行不存在对应键值对时,用null作为默认值。处理嵌套数组的select过滤逻辑时遇到问题,寻求解决方法。

输入示例

{
  "id": "123",
  "details": [
    {
      "headerText": "ignore_me",
      "rows": [
        {
          "key": "label1",
          "val": "sdhf"
        },
        {
          "key": "label2",
          "val": "fdgg"
        }
      ]
    },
    {
      "headerText": "only_look_at_kvs_here",
      "rows": [
        {
          "key": "label3",
          "val": "abc"
        },
        {
          "key": "label4",
          "val": "def"
        },
        {
          "key": "label5",
          "val": "qwe"
        }
      ]
    }
  ]
}
{
  "id": "345",
  "details": [
    {
      "headerText": "ignore_me",
      "rows": [
        {
          "key": "label1",
          "val": "abc"
        },
        {
          "key": "label2",
          "val": "def"
        }
      ]
    },
    {
      "headerText": "only_look_at_kvs_here",
      "rows": [
        {
          "key": "label1",
          "val": "foo"
        },
        {
          "key": "label2",
          "val": "bar"
        }
      ]
    }
  ]
}
{
  "id": "789",
  "details": [
    {
      "headerText": "ignore_me",
      "rows": [
        {
          "key": "label1",
          "val": "abc"
        },
        {
          "key": "label2",
          "val": "def"
        }
      ]
    }
  ]
}

预期输出

{
  "id": "123",
  "label1": null,
  "label2": null,
  "label3": "abc",
  "label4": "def"
}
{
  "id": "345",
  "label1": "foo",
  "label2": "bar",
  "label3": null,
  "label4": null
}
{
  "id": "789",
  "label1": null,
  "label2": null,
  "label3": null,
  "label4": null
}

尝试的命令

jq '{id, "label1": (.details[] | select(.headerText=="only_look_at_kvs_here") | .rows[] | select(.key=="label1") | .val) }'

解决方法

原命令的问题在于:当没有匹配的details项或rows项时,select会直接过滤掉该结果,导致对应字段缺失而非返回null。可以通过以下jq命令实现需求:

jq '
  .target_rows = (.details[] | select(.headerText == "only_look_at_kvs_here") | .rows) // [] |
  .target_rows |= from_entries |
  {
    id,
    label1: .target_rows.label1 // null,
    label2: .target_rows.label2 // null,
    label3: .target_rows.label3 // null,
    label4: .target_rows.label4 // null
  } |
  del(.target_rows)
'

命令解释

  1. 定位目标行:通过.details[] | select(...)找到headerText为only_look_at_kvs_here的details项,提取其rows数组;如果没有匹配项,用// []返回空数组,避免后续处理出错。
  2. 转换为键值对对象:用from_entries将rows数组(每个元素是{key, val}结构)转换为普通键值对对象,方便直接取值。
  3. 构造结果对象:指定需要的label1到label4字段,用// null确保当目标对象中没有对应键时,自动填充null。
  4. 清理临时字段:删除临时创建的target_rows字段,得到最终的预期输出。

内容的提问来源于stack exchange,提问作者Daniel Resnick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:14:55