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

如何在jq中排除特定子树,修改其余节点的x键值?

如何用jq替换非to_exclude子树中所有"x"键的值为"anything"

问题背景

给定如下JSON输入:

{
  "to_exclude": {
    "x": "something",
    "aa": {
      "x": "something",
      "aaa": {
        "x": "something"
      }
    }
  },
  "a": {
    "x": "something else",
    "aa": {
      "x": "something else",
      "aaa": {
        "x": "something else"
      }
    }
  },
  "b": {
    "x": "something else",
    "bb": {
      "x": "something else",
      "bbb": {
        "x": "something else"
      }
    }
  },
  "...": {
    "x": "something else",
    "......": {
      "x": "something else",
      ".........": {
        "x": "something else"
      }
    }
  }
}

需求是:将所有不属于to_exclude子树的"x"键值替换为"anything",预期输出如下:

{
  "to_exclude": {
    "x": "something",
    "aa": {
      "x": "something",
      "aaa": {
        "x": "something"
      }
    }
  },
  "a": {
    "x": "anything",
    "aa": {
      "x": "anything",
      "aaa": {
        "x": "anything"
      }
    }
  },
  "b": {
    "x": "anything",
    "bb": {
      "x": "anything",
      "bbb": {
        "x": "anything"
      }
    }
  },
  "...": {
    "x": "anything",
    "......": {
      "x": "anything",
      ".........": {
        "x": "anything"
      }
    }
  }
}

目前已经掌握相反操作(修改to_exclude子树下所有"x"键值)的简洁jq代码:

.to_exclude |= (.. |= ( if type == "object" and has("x") then .x = "anything" else . end))

该代码的输出为:

{
  "to_exclude": {
    "x": "anything",
    "aa": {
      "x": "anything",
      "aaa": {
        "x": "anything"
      }
    }
  },
  "a": {
    "x": "something else",
    "aa": {
      "x": "something else",
      "aaa": {
        "x": "something else"
      }
    }
  },
  "b": {
    "x": "something else",
    "bb": {
      "x": "something else",
      "bbb": {
        "x": "something else"
      }
    }
  },
  "...": {
    "x": "something else",
    "......": {
      "x": "something else",
      ".........": {
        "x": "something else"
      }
    }
  }
}

请问如何用类似简洁的方式实现目标需求?


解决方案

可以采用「先全局替换,再恢复目标子树」的思路,代码简洁且逻辑清晰:

($in | .to_exclude) as $original_exclude
| (.. |= (if type == "object" and has("x") then .x = "anything" else . end))
| .to_exclude = $original_exclude

代码解释

  1. ($in | .to_exclude) as $original_exclude:先将原始JSON中的to_exclude子树保存到变量$original_exclude中,避免后续替换操作覆盖它。
  2. (.. |= (if type == "object" and has("x") then .x = "anything" else . end)):遍历整个JSON结构,将所有包含"x"键的对象中的"x"值替换为"anything"(这一步会同时修改to_exclude里的x)。
  3. .to_exclude = $original_exclude:将之前保存的原始to_exclude子树重新赋值回去,恢复其中所有"x"的原始值。

执行这段代码后,就能得到预期的输出结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 02:12:33