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

如何使用yq为YAML树中任意层级的responses对象新增属性

问题说明

处理OpenAPI规范的YAML文件时,需要为所有键名为responses的对象统一新增一条响应配置,尝试多种写法均未达到预期,暂未定位到yq语法的具体问题点。
涉及的示例YAML文件结构如下:

openapi: 3.0.1
info:
  title: my service
  description: API for my service
  version: 1.0.0
security:
  - jwt:
    - read
paths:
  '/foo/{fooId}/firmware/update-request':
    post:
      parameters:
        - name: fooId
          in: path
          description: Foo Id
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FooRequest'
            example:
              firmwareVersion: "0.1"
      responses:
        '202':
          description: Foo has been done
        '400':
          $ref: '#/components/responses/BadRequest'
        '409':
          $ref: '#/components/responses/Conflict'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'
        '502':
          $ref: '#/components/responses/BadGateway'
  '/foo/{fooId}/firmware/auto-update':
    put:
      parameters:
        - name: fooId
          in: path
          description: Foo Id
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FooUpdate'
            example:
              enabled: true
      responses:
        '204':
          description: Foo update
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'
        '502':
          $ref: '#/components/responses/BadGateway'
   # 后续还有大量同类路径配置
目标效果

在完全保留原有文件结构的前提下,所有responses节点都新增指定响应条目,原有配置保持不变,效果示例:

responses:
  '204':
    description: Foo update
  # ... 其余原有响应配置保持不变
  'xxx':
    description: yyy
问题排查

之前尝试的命令如下:

yq -i '.. | select(has("responses")).responses | . += {"xxx": {"description": yyy}}' my.yaml

该写法的问题在于:管道符会将前一步的输出作为后一步的处理上下文,最终整个命令只输出所有匹配到的responses节点内容,根节点到responses路径上的其他无关节点会被全部过滤丢弃。

正确实现方案

使用mikefarah/yq v4版本时,执行以下命令即可满足需求:

yq -i '(.. | select(type == "object" and has("responses")).responses) += {"xxx": {"description": "yyy"}}' my.yaml

语法说明:

  • 用括号包裹目标节点匹配表达式,将其指定为更新操作的目标路径,而非通过管道过滤输出结果,因此会完整保留原始文档的所有结构
  • 增加type == "object"判断,避免遍历到数组、字符串等非对象类型节点时调用has()方法触发报错
  • +=操作会在原有responses节点的配置基础上追加新的响应条目,不会覆盖原有配置

内容的提问来源于stack exchange,提问作者Sven-Michael Stübe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:45:34