使用缩进将JSON合并到YAML中
我正在尝试将JSON合并到YAML文件中。使用缩进将JSON合并到YAML中,json,ruby,yaml,chef-infra,Json,Ruby,Yaml,Chef Infra,我正在尝试将JSON合并到YAML文件中。 YAML如下所示: filebeat.inputs: - type: log <incorporate here with a single level indent> enabled: true paths: 我想将其合并到现有YAML中。 我尝试使用: JSON.parse((a).to_json).to_yaml 在应用这个之后,我得到了一个有效的YAML,但没有缩进(所有行都必须缩进),并且带有一个“--
YAML如下所示:
filebeat.inputs:
- type: log
<incorporate here with a single level indent>
enabled: true
paths:
我想将其合并到现有YAML中。我尝试使用:
JSON.parse((a).to_json).to_yaml
在应用这个之后,我得到了一个有效的YAML,但没有缩进(所有行都必须缩进),并且带有一个“--”,这是Ruby在YAML中的新文档。结果是:
filebeat.inputs:
- type: log
---
processors:
drop_event:
when:
or:
- equals:
status: 500
- equals:
status: -1
enabled: true
我想要的结果是:
filebeat.inputs:
- type: log
processors:
drop_event:
when:
or:
- equals:
status: 500
- equals:
status: -1
enabled: true```
为了做到这一点,首先需要将原始YAML转换为JSON
original = YAML.load(File.read(File.join('...', 'filebeat.inputs')))
# => [
{
"type": "log",
"enabled": true,
"paths": null
}
]
然后您必须将JSON
合并到这个原始变量中
original[0].merge!(a.stringify_keys)
original.to_yaml
# =>
---
-
type: log
enabled: true
paths:
processors:
drop_event:
when:
or:
- equals:
status: 500
- equals:
status: -1
通过合并散列,然后将结果序列化为YAML,生成有效的ruby对象比反之更容易
puts(yaml.map do |hash|
hash.each_with_object({}) do |(k, v), acc|
# the trick: we insert before "enabled" key
acc.merge!(JSON.parse(a.to_json)) if k == "enabled"
# regular assignment for all hash elements
acc[k] = v
end
end.to_yaml)
结果:
---
- type: log
processors:
drop_event:
when:
or:
- equals:
status: 500
- equals:
status: -1
enabled: true
JSON.parse(a.to_JSON)
基本上将符号转换为字符串。这不会保留结果哈希的顺序。另外,这会将yaml
中的键转换为符号,从而使它们变得混乱。@AlekseiMatiushkin Ruby哈希的顺序没有任何保证,实际上,这没有任何意义,JSON和yaml都是键值文件格式,根本不考虑顺序。保持此顺序有任何目的吗?完全错误。自v2.0(甚至可能是v1.9,)以来,ruby Hash的顺序确实有一个保证,您无法为OP做出决定。也许它是由关心顺序的第三方库解析的。我们基本上在YAML中有一个Filebeat配置文件。与其说是顺序,不如说是缩进。维持秩序对我们来说更容易。YAML文件已经在我们的存储库中,并在资源调配期间由Chef注入。
---
- type: log
processors:
drop_event:
when:
or:
- equals:
status: 500
- equals:
status: -1
enabled: true