如何删除 YAML 文件中特定标头的所有特定子部分?

Dav*_*ave 4 yaml

我正在使用 bash shell。我有一个 YAML 文件,我想从中删除某些文本块。

  /image-content:
    post:
      operationId: createEventPublic
      summary: Process events
      description: Process events
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Content'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Content'
  /text-content:
    post:
      operationId: createStaticText
      summary: Process text events
      description: Process text events
      parameters: []
      requestBody:
    ...
Run Code Online (Sandbox Code Playgroud)

我想删除(例如)路径包含“图像内容”的文本块。通常我可以用它来删除带有该文本的一行

sed -i '/image-content/d' ./infile
Run Code Online (Sandbox Code Playgroud)

但我不太清楚如何替换之后的每一行,直到下一行以两个空格和一个“/”(例如“/”)开头。在上面,我想删除所有内容,直到

  /text-content:
Run Code Online (Sandbox Code Playgroud)

编辑:虽然这可能不是有效的 openapi 3 swagger,但我相信它仍然是一个有效的 YAML 文件

openapi: 3.0.0
components:
  /static/image-content:
    post:
      type: hello
  /api/hello:
    post:
      type: hello
  /static/css-content:
    post:
      type: hello
Run Code Online (Sandbox Code Playgroud)

最后,我想删除以“/static”开头的块。所以结束文档将是

openapi: 3.0.0
components:
  /api/hello:
    post:
      type: hello
Run Code Online (Sandbox Code Playgroud)

Kus*_*nda 9

yq -y 'del(."/image-content")' file.yml
Run Code Online (Sandbox Code Playgroud)

这使用yqfrom https://kislyuk.github.io/yq//image-content使用del()命令从 YAML 文档中删除顶级部分。

鉴于问题中的示例文档,这将导致以下 YAML 文档被写入终端:

/text-content:
  post:
    operationId: createStaticText
    summary: Process text events
    description: Process text events
    parameters: []
    requestBody: null
Run Code Online (Sandbox Code Playgroud)

如果您想保存它,请将其重定向到一个新文件,或者使用该--in-place选项进行就地编辑(当然,在没有该选项的情况下先进行测试之后)。

yq是 JSON parser 的包装器jq,允许使用jq表达式来处理 YAML 文件。


如果有问题的文档是局部的,并没有显示其真正的结构(压痕额外的两个空间意味着我们现在看到的是一个中等水平的部分),那么你可能需要使用

yq -y 'del(.[]."/image-content")' file.yml
Run Code Online (Sandbox Code Playgroud)

.[]."/image-content"表达指的是“/image-content位于顶层之下的任何部分”。

递归搜索和删除/image-content部分,无论它们可能出现在文档中的哪个位置,请使用

yq -y 'del(.. | ."/image-content"?)' file.yml
Run Code Online (Sandbox Code Playgroud)

中使用的表达式del()递归地遍历文档结构 using..并拉出任何名为 的部分/image-content,其中有一个部分(这对应//于 XPath 查询中的运算符)。然后删除这些。


解决您更新的问题:

yq -y '.components |= with_entries(del(select(.key | startswith("/static/"))) // empty)' file.yml
Run Code Online (Sandbox Code Playgroud)

这将更新components利用其小节,暂时把他们变成独立的部分keyvalue值(见文档with_entries()jq手册),选择并删除与开始以实际字符串键的那些/static/

// empty位:该del()操作结果中null值。这些不能从keyvalue值返回到适当的子部分,所以我将它们改为empty值,这使它们完全消失。老实说,我并不完全确定围绕这一点的内部运作。

这导致

openapi: 3.0.0
components:
  /api/hello:
    post:
      type: hello
Run Code Online (Sandbox Code Playgroud)