【问题标题】:Incorporate JSON into YAML with Indentation使用缩进将 JSON 合并到 YAML
【发布时间】:2019-06-25 04:39:25
【问题描述】:

我正在尝试将 JSON 合并到 YAML 文件中。
YAML 看起来像这样:
文件节拍输入:

- type: log  
  <incorporate here with a single level indent>
  enabled: true  
  paths:  

假设你有以下变量:

a = { processors: { drop_event: { when: { or: [ {equals: { status: 500 }},{equals: { status: -1 }}]}}}}  

我想将它合并到现有的 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```

【问题讨论】:

    标签: json ruby yaml chef-infra


    【解决方案1】:

    通过合并哈希生成有效的 ruby​​ 对象并然后将结果序列化为 YAML 比反之更容易。

    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) 基本上是将符号转换为字符串。

    【讨论】:

      【解决方案2】:

      首先,您需要将原始 YAML 转换为 JSON

      original = YAML.load(File.read(File.join('...', 'filebeat.inputs')))
      # => [
             {
               "type": "log", 
               "enabled": true, 
               "paths": null
             }
           ]
      

      然后你必须将你的JSON 合并到这个original 变量中

      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 中的键转换为符号。
      • @AlekseiMatiushkin 没有保证 Ruby 哈希的顺序,实际上,这没有任何意义,JSON 和 YAML 都是键值文件格式,根本不关心顺序
      • 保持这个订单有什么目的吗?
      • 完全错误。 确实从 v2.0(甚至可能是 v1.9)开始按 ruby​​ 哈希的顺序提供保证,您无法为 OP 做出决定。也许它是由关心订单的 3rd 方库解析的。
      • 我们基本上在 YAML 中有一个 Filebeat 配置文件。它更多的是关于缩进而不是顺序。保持订单对我们来说更容易查看。 YAML 文件已经在我们的存储库中,并由 Chef 在配置期间注入。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-05
      • 2019-01-25
      • 2020-05-23
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多