如果您的系统上安装了 python,您可以执行 pip install ruamel.yaml.cmd¹ 然后:
yaml merge-expand input.yaml output.yaml
(将output.yaml 替换为- 以写入标准输出)。这实现了合并扩展,保留了密钥顺序和 cmets。
上面实际上是利用ruamel.yaml¹的几行代码
因此,如果您有 Python(2.7 或 3.4+)并使用pip install ruamel.yaml 安装它并将以下内容另存为expand.py:
import sys
from ruamel.yaml import YAML
yaml = YAML(typ='safe')
yaml.default_flow_style=False
with open(sys.argv[1]) as fp:
data = yaml.load(fp)
with open(sys.argv[2], 'w') as fp:
yaml.dump(data, fp)
你已经可以做到了:
python expand.py input.yaml output.yaml
这将为您提供在语义上与您请求的内容等效的 YAML(在 output.yaml 中,映射的键已排序,在此程序输出中它们不是)。
以上假设您的 YAML 中没有任何标签,也不关心保留任何 cmets。其中大部分以及密钥顺序可以通过使用标准YAML() 实例的修补版本来保留。修补是必要的,因为标准的 YAML() 实例也保留了往返的合并,这正是您不想要的:
import sys
from ruamel.yaml import YAML, SafeConstructor
yaml = YAML()
yaml.Constructor.flatten_mapping = SafeConstructor.flatten_mapping
yaml.default_flow_style=False
yaml.allow_duplicate_keys = True
# comment out next line if you want "normal" anchors/aliases in your output
yaml.representer.ignore_aliases = lambda x: True
with open(sys.argv[1]) as fp:
data = yaml.load(fp)
with open(sys.argv[2], 'w') as fp:
yaml.dump(data, fp)
使用此输入:
default: &DEFAULT
URL: website.com
mode: production
site_name: Website
some_setting: h2i8yiuhef
some_other_setting: 3600 # an hour?
development:
<<: *DEFAULT
URL: website.local # local web
mode: dev
test:
<<: *DEFAULT
URL: test.website.qa
mode: test
这将给出此输出(请注意,合并的键上的 cmets 会重复):
default:
URL: website.com
mode: production
site_name: Website
some_setting: h2i8yiuhef
some_other_setting: 3600 # an hour?
development:
URL: website.local # local web
mode: dev
site_name: Website
some_setting: h2i8yiuhef
some_other_setting: 3600 # an hour?
test:
URL: test.website.qa
mode: test
site_name: Website
some_setting: h2i8yiuhef
some_other_setting: 3600 # an hour?
以上是本答案开头提到的yaml merge-expand 命令的作用。
¹ 免责声明:我是该软件包的作者。