如何用PyYAML将输出“合并”到现有的YAML文件中?
我想把一些数据从一个字符串添加到 foo.yaml 文件中,字符串的样子是这样的:
foo.yaml
# other stuff in the file
packages: # doesn't have to exist
- 1
- 2
- 3
# other stuff in the file
这个字符串
packages:
- 4
- 5
这两个文件的格式不总是一样的。我不能简单地把其他内容加到后面,因为 packages:
这个部分可能已经存在,而且如果存在的话,它不一定是在文件的最后面。
我试过直接把内容加到文件里,但我发现这样不行,因为 packages:
可能已经存在。另外,当我尝试那样添加内容时,字符串中的换行符被写成了 \n
符号,而不是实际的换行。
1 个回答
1
你不应该使用PyYAML来处理这个问题。因为它只支持旧版的YAML 1.1规范,这个规范在2009年就已经过时了。而且,PyYAML会很乐意地删除你YAML文件中的任何注释。
你可以使用ruamel.yaml
来加载这两个文件,然后用setdefault和extend来更新第一个文件,以应对packages
可能在第一个文件中不存在的情况:
import sys
import ruamel.yaml
from pathlib import Path
yaml = ruamel.yaml.YAML()
yaml.indent(sequence=4, offset=2)
yaml.preserve_quotes = True
foo = yaml.load(Path('foo.yaml'))
extra = yaml.load(Path('extra.yaml'))
# optionally move comment
if 'packages' in foo:
fpc = foo['packages'].ca
l = len(foo['packages']) - 1
if l in fpc.items:
le = len(extra['packages']) + l
foo['packages'].ca.items[le] = fpc.items.pop(l)
foo.setdefault('packages', []).extend(extra['packages'])
yaml.dump(foo, sys.stdout)
这样做会得到:
# other stuff in the file
packages: # doesn't have to exist
- 1
- 2
- 3
- 4
- 5
# other stuff in the file
第二个# other stuf in the file
注释会被附加到序列的最后一个元素上。从这个序列加载的列表在扩展时不会移动这个注释,下面的可选代码是为了将这个注释明确地移动到新序列的末尾。
免责声明:我是ruamel.yaml
的作者。