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

如何用单条jq语句处理未知嵌套深度的JSON删除操作

问题描述

更新记录

  • 更新2:使用递归..确实能处理任意深度的JSON结构,当匹配type == "cow"或type == "lion"时,可按要求返回简化或保留父结构的结果。
  • 更新1:调整JSON结构贴合真实场景后,添加any()能正确删除.car[]、.boat[]的匹配值,但.plane的整条记录会被误删。

需求

需要修改jq语句实现两种输出:

  1. 匹配type == "dog"时,删除car下包含该类型的子节点,保留car及其他子节点:
jq 'del(.car[], .boat[], .plane | select(any(.type == "dog")))' 
// 预期输出
{
  ...
   "car":{ "delta": {...} }
  ...
}
  1. 匹配type == "lion"时,删除plane下包含该类型的子节点,保留plane及其他子节点:
jq 'del(.car[], .boat[], .plane | select(any(.type == "lion")))' 
// 预期输出
{ 
 ...
   "plane":{ "delta": {} }
 ...
}

尝试过的方法

曾尝试用select(.[-1] == "lion")替换select(.[].type == "lion"),但未生效;调整左侧路径为... .plane[]) | select(.type == "lion")?时,.car[]的匹配逻辑会失效。

核心问题

如何用单条jq语句处理未知嵌套深度的场景(比如car > type为3层,plane > type为2层),平衡路径选择和条件匹配的深度,只删除目标子节点而保留父结构。

测试用JSON结构

{
  "www":"hello",  
  "car": {
    "alpha": {
      "in": {
        "model": "alpha",
        "dir": "in",
        "type": "dog"
      },
      "out": {
        "model": "alpha",
        "dir": "out",
        "type": "dog"
      }
    },
    "delta": {
      "in": {
        "model": "delta",
        "dir": "in",
        "type": "bird"
      },
      "out": {
        "model": "delta",
        "dir": "out",
        "type": "bird"
      }
    }
  },
  "boat":{
    "beta": {
      "in": {
        "model": "beta",
        "dir": "in",
        "type": "mouse"
      }
    }
  },
  "plane":{
      "beta": {
        "model": "beta",
        "dir": "in",
        "type": "lion"
      },
      "delta": {
        "model": "delta",
        "dir": "in",
        "type": "bee"
      }
  }
}

解决方案

使用递归遍历..结合any(),针对car、boat、plane的直接子节点进行筛选,删除那些自身或后代包含目标type值的节点:

匹配type == "dog"的语句

del(
  .car[] | select(any(..; .type == "dog")),
  .boat[] | select(any(..; .type == "dog")),
  .plane[] | select(any(..; .type == "dog"))
)

匹配type == "lion"的语句

del(
  .car[] | select(any(..; .type == "lion")),
  .boat[] | select(any(..; .type == "lion")),
  .plane[] | select(any(..; .type == "lion"))
)

通用化单条语句(通过变量指定目标type)

--arg target "dog" 'del(
  .car[] | select(any(..; .type == $target)),
  .boat[] | select(any(..; .type == $target)),
  .plane[] | select(any(..; .type == $target))
)'

原理说明

  • .car[]、.boat[]、.plane[]分别定位到三个顶级对象的直接子节点;
  • any(..; .type == $target)递归遍历当前节点的所有后代(包括自身),判断是否存在符合条件的type值;
  • del()只删除被选中的直接子节点,保留car、boat、plane本身及其他未匹配的子节点,完美适配不同嵌套深度的场景。

内容的提问来源于stack exchange,提问作者art vanderlay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:17:49