我有一个YAML文件,如下所示:

api: v1
hostname: abc
metadata:
  name: test
  annotations: {
    "ip" : "1.1.1.1",
    "login" : "fad-login",
    "vip" : "1.1.1.1",
    "interface" : "port1",
    "port" : "443"
  }

我试图从文件中读取这些数据,只替换ipvip的值,然后将其写回文件.

我try 的是:

open ("test.yaml", w) as f:
    yaml.dump(object, f) #this does not help me since it converts the entire file to YAML

json.dump()也不起作用,因为它将整个文件转换为JSON.它需要相同的格式,但值需要更新.我该怎么做?

推荐答案

你所拥有的不是带有嵌入式JSON的YAML,而是带有annotations的值的YAML

这将是

api: v1
hostname: abc
metadata:
  name: test
  annotations: |
    {
      "ip" : "1.1.1.1",
      "login" : "fad-login",
      "vip" : "1.1.1.1",
      "interface" : "port1",
      "port" : "443"
    }

这里annotations的值是一个字符串,您可以将其交给JSON解析器.

您只需加载文件,修改并转储即可.这将改变布局

import sys
import ruamel.yaml

file_in = Path('input.yaml')
    
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.width = 1024
data = yaml.load(file_in)
annotations = data['metadata']['annotations']
annotations['ip'] = type(annotations['ip'])('4.3.2.1')
annotations['vip'] = type(annotations['vip'])('1.2.3.4')
yaml.dump(data, sys.stdout)

它给出:

api: v1
hostname: abc
metadata:
  name: test
  annotations: {"ip": "4.3.2.1", "login": "fad-login", "vip": "1.2.3.4", "interface": "port1", "port": "443"}

type(annotations['vip'])()确定输出中的替换字符串具有相同的

ruamel.yaml当前不会在流样式映射/序列中保留换行符.

import sys
import ruamel.yaml

file_in = Path('input.yaml')

def rewrite_closing_curly_brace(s):
    res = []
    for line in s.splitlines():
        if line and line[-1] == '}':
            res.append(line[:-1])
            idx = 0
            while line[idx] == ' ':
                idx += 1
            res.append(' ' * (idx - 2) + '}')
            continue
        res.append(line)
    return '\n'.join(res) + '\n'
    
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.width = 15
data = yaml.load(file_in)
annotations = data['metadata']['annotations']
annotations['ip'] = type(annotations['ip'])('4.3.2.1')
annotations['vip'] = type(annotations['vip'])('1.2.3.4')
yaml.dump(data, sys.stdout, transform=rewrite_closing_curly_brace)

它给出:

api: v1
hostname: abc
metadata:
  name: test
  annotations: {
    "ip": "4.3.2.1",
    "login": "fad-login",
    "vip": "1.2.3.4",
    "interface": "port1",
    "port": "443"
  }

在这里,宽度的15当然高度依赖于文件,如果其他行

请注意,您的原始输出和转换后的输出是无效的YAML,

Json相关问答推荐

如何使用JQ有条件 Select 值

合并2个嵌套词典

bash用jq获取第二条JSON记录

使用 jq,如何将两个属性构成键的对象数组转换为对象的索引对象?

如何使用jolt规范将一个对象添加到另一个对象中并删除该对象

用于遮蔽卡的 Jolt 规格

Rails 控制器无需编码即可渲染 json

JQuery,使用 GET 方法发送 JSON 对象

如何使用 jackson 反序列化为 Kotlin 集合

单元测试球衣 Restful Services

如何使用 Newtonsoft.Json 反序列化 JSON 数组

在 Apache Spark 中读取多行 JSON

Spring MVC 4:application/json内容类型设置不正确

使用 c# 通用地展平 Json

如何使用 C# 将 JSON 文本转换为对象

错误未判断调用put(K, V)作为原始类型java.util.HashMap的成员

为不同类型的项目数组正确的 JSON Schema

在android中读取Json数组

如何判断 JSON 响应元素是否为数组?

有什么方法可以判断您安装的 gulp 版本吗?