努力使用 ruamel roundtrip 添加和删除空行

Struggling to add and remove blank lines with ruamel roundtrip

我有一个很大的 YAML 文件,我需要在其中的一项末尾添加 2 个键值对。
这是原始文件格式的示例:

repo1:
  description: sample description
  team: sample team

repo2:
  description: sample description
  team: sample team

我希望输出如下所示:

repo1:
  description: sample description
  team: sample team
  archived: true
  archived_date: sample date

repo2:
  description: sample description
  team: sample team

我正在使用 ruamel.yaml,因为往返将格式和评论保留在这个大文件的顶部。我执行此操作的代码如下,它需要输入 repo_name 这是我要添加到的项目:

from ruamel.yaml import YAML

yaml = YAML()
with open("repos.yml", "r") as file:
  repos = yaml.load(file)
for repo in repos.items():
  if repo_name == repo[0]:
    repo[1].update({"archived": bool("true"), "archived_date": datetime.today().strftime('%d-%m-%Y')})
    break
  else:
    continue

with open("repos.yml", "w") as processed_file:
  yaml.default_flow_style = False
  yaml.width = float("inf")
  yaml.dump(repos, processed_file)

这几乎可以满足我的要求,但输出如下所示:

repo1:
  description: sample description
  team: sample team

  archived: true
  archived_date: sample date
repo2:
  description: sample description
  team: sample team

如何删除包含内容之前的空行并在其后添加一个空行?在循环中打印 repo[1] 显示字典没有空行,但我想使用往返来保留其余格式。

如果在加载后检查评论属性,.ca,对于 repos['repo1'],您会看到:

Comment(comment=None,
  items={'team': [None, None, CommentToken('\n\n', line: 3, col: 8), None]})

所以由空 EOL 注释后跟空行 ('\n\n') 组成的“注释”是 附加到 team 密钥,这是您要移动到新的最新密钥的密钥:

import sys
from datetime import date
from ruamel.yaml import YAML

yaml_str = """
repo1:
  description: sample description
  team: sample team

repo2:
  description: sample description
  team: sample team
"""

repo_name = 'repo1'

yaml = YAML()
# yaml.default_flow_style = False
yaml.width = 2048

repos = yaml.load(yaml_str)
for repo in repos.items():
  if repo_name == repo[0]:
    repo[1].update(dict(archived=True, archived_date=date.today().strftime('%d-%m-%Y')))
    break
  else:
    continue

ca_items = repos['repo1'].ca.items
ca_items['archived_date'] = ca_items.pop('team')
yaml.dump(repos, sys.stdout)

给出:

repo1:
  description: sample description
  team: sample team
  archived: true
  archived_date: 17-12-2021

repo2:
  description: sample description
  team: sample team
  • 确保您的代码 install/check 是您找到的 ruamel.yaml 的修订号 这个工作。内部可能会在某些时候发生变化。
  • 您可以使代码更健壮,方法是遍历键并检测最后一个元素的键名,并确保它在重新分配之前有注释。
  • 行列信息不需要更新。
  • YAML 文件的推荐扩展名(根据 yaml.org 常见问题解答)已经 .yaml 超过 15 年了。
  • bool("true")bool("false") 都转储到 YAML 中的 true,而 bool("") 转储到 false。它 在你的字典更新中使用 TrueFalse 更清楚。