jth*_*son 7 python yaml reformatting
我正在寻找一种可以轻松获取包含锚,别名和合并键的YAML文件并扩展别名并将其合并为平面YAML文件的工具或过程。仍然有许多不完全支持合并的常用YAML解析。
我希望能够利用合并使事情保持干燥的优势,但是在某些情况下,需要将其构建到更详细的“扁平” YAML文件中,以便其他依赖不完整工具的工具可以使用它YAML解析器。
源YAML示例:
default: &DEFAULT
URL: website.com
mode: production
site_name: Website
some_setting: h2i8yiuhef
some_other_setting: 3600
development:
<<: *DEFAULT
URL: website.local
mode: dev
test:
<<: *DEFAULT
URL: test.website.qa
mode: test
Run Code Online (Sandbox Code Playgroud)
所需的输出YAML:
default:
URL: website.com
mode: production
site_name: Website
some_setting: h2i8yiuhef
some_other_setting: 3600
development:
URL: website.local
mode: dev
site_name: Website
some_setting: h2i8yiuhef
some_other_setting: 3600
test:
URL: test.website.qa
mode: test
site_name: Website
some_setting: h2i8yiuhef
some_other_setting: 3600
Run Code Online (Sandbox Code Playgroud)
我最近使用 yaml 进行了锚点的扩展
yq 'explode(.)' input.yaml > output.yaml
Run Code Online (Sandbox Code Playgroud)
这是使用golang yq。
如果您的系统上安装了python,则可以做pip install ruamel.yaml.cmd¹然后:
yaml merge-expand input.yaml output.yaml
Run Code Online (Sandbox Code Playgroud)
(替换output.yaml用-写入标准输出)。这实现了合并扩展并保留了关键顺序和注释。
上面实际上是几行利用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)
Run Code Online (Sandbox Code Playgroud)
您已经可以:
python expand.py input.yaml output.yaml
Run Code Online (Sandbox Code Playgroud)
这将使您的YAML在语义上等同于您所请求的YAML(在output.yaml映射的键中排序,在此程序输出中不是)。
以上假设您的YAML中没有任何标签,也不在乎保留任何注释。通过使用标准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)
Run Code Online (Sandbox Code Playgroud)
使用此输入:
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
Run Code Online (Sandbox Code Playgroud)
这将给出此输出(请注意,对合并的键的注释会重复):
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?
Run Code Online (Sandbox Code Playgroud)
以上是yaml merge-expand此答案开头提到的命令的作用。
¹ 免责声明:我是该软件包的作者。
| 归档时间: |
|
| 查看次数: |
1197 次 |
| 最近记录: |