我正在尝试使用PyYAML和Python3来编辑YAML文件中的值(它是一个Hiera数据结构,但这只是一点点。)
使用yaml.safe_load
和yaml.dump
很容易实现。我遇到的问题是我需要保留注释,空格,排序和其他格式。也就是说,当我编辑给定键的值时,应该是文件中的唯一更改。 (不需要自己添加或删除密钥。)
就我而言,这些是二级密钥。我可以使用正则表达式或某种形式的状态机来完成它 - 但它非常讨厌。是否有人知道图书馆已经整齐地做到了这一点?
这是有关YAML的一个愚蠢的例子:
---
# Some form of comment block.
# Some form of comment block.
# Some form of comment block.
# This is my config block.
config::me:
key0: 123
key1: 456
# This is another config block:
applications:
frontend:
version: '2.4.2'
enabled: true
backend:
version: '4.3.9'
enabled: false
# More comments etcetera.
基本上我需要做的是定位applications.frontent.version
并将值从2.4.2
更新为2.4.3
,而不触及文件中的任何其他内容。
答案 0 :(得分:0)
你可以使用ruamel.yaml
作为PyYAML¹的衍生物。它特别创建用于执行这种往返,保留注释以及原始文件中的其他一些内容,大多数解析器在往返过程中丢弃(它也是YAML 1.2兼容,而PyYAML支持1.1)
import sys
import ruamel.yaml
from ruamel.yaml.util import load_yaml_guess_indent
from ruamel.yaml.scalarstring import SingleQuotedScalarString
ys = """\
---
# Some form of comment block.
# Some form of comment block.
# Some form of comment block.
# This is my config block.
config::me:
key0: 123
key1: 456
# This is another config block:
applications:
frontend:
version: '2.4.2'
enabled: true
backend:
version: '4.3.9'
enabled: false
# More comments etcetera.
"""
data, indent, block_seq_indent = load_yaml_guess_indent(ys, preserve_quotes=True)
data['applications']['frontend']['version'] = SingleQuotedScalarString('2.4.3')
ruamel.yaml.round_trip_dump(data, sys.stdout, explicit_start=True)
给你:
---
# Some form of comment block.
# Some form of comment block.
# Some form of comment block.
# This is my config block.
config::me:
key0: 123
key1: 456
# This is another config block:
applications:
frontend:
version: '2.4.3'
enabled: true
backend:
version: '4.3.9'
enabled: false
# More comments etcetera.
只有preserve_quotes
选项和SingleQuotedScalarString()
的使用才有必要,因为您在标量2.4.3
和4.3.9
周围都有引号,这些引号是多余的,通常会被删除。
¹免责声明:我是ruamel.yaml
的作者。