加载和修改 YAML 而不破坏缩进?

发布于 2025-01-10 13:16:10 字数 972 浏览 0 评论 0原文

您好,我想将 x 的整数值更新为 8,但我无法很好地理解如何才能做到这一点而不会对 sub 内的缩进产生任何影响 在 yaml 文件中。我想读取此 YAML 文件,将字符串替换为 x=8 并按原样保存 yaml 文件。

我使用Python进行修改,示例代码如下:

parent:
- 
  subchild: something
  subchild2: something
    - sub: 
        y = 4; 
        x = 6 # I wanted to replace this integer to 8  
        z = 10

注意点x=6将在多个文件中,所以我想一个一个地打开文件,并进行所有修改(x=8)并一一保存这些文件。

问题

我能够替换该文件,但我面临的问题是,结果变成了这样:

parent:
- 
  subchild: something
  subchild2: something
    - sub: y = 4; x = 8; z = 10;

我想要的是 sub 中与原始文件中相同的缩进yaml 文件。希望你在这里明白了。

[编辑]附加信息:

这是我读取文件和保存文件的方式。

f = open(test.yaml, 'r')      
newf = f.read().replace('6', '8')
overrides = yaml.load(newf)
f.close()
with open('updated_test.yaml', 'w') as ff:
yaml.dump(overrides, ff)

Hi wanted to update this integer value of x to 8 but I could not get any good understanding on how can I do that without making any effect in indents inside sub in yaml file. I wanted to read this YAML file, replace the string to x=8 and save the yaml file as it is.

I am using Python for the modification, here is the sample code:

parent:
- 
  subchild: something
  subchild2: something
    - sub: 
        y = 4; 
        x = 6 # I wanted to replace this integer to 8  
        z = 10

Note Point: x=6 will be in multiple files, so I wanted to open files one by one, and do all the modifications ( x=8) and save those files one by one.

Problem

I was able to replace the file but what the problem I am facing is, the result becomes this:

parent:
- 
  subchild: something
  subchild2: something
    - sub: y = 4; x = 8; z = 10;

And what I want is the same indents inside sub as in the original yaml file. Hope you got point here.

[EDIT] Additional information:

This is the way I am reading the file and saving the file.

f = open(test.yaml, 'r')      
newf = f.read().replace('6', '8')
overrides = yaml.load(newf)
f.close()
with open('updated_test.yaml', 'w') as ff:
yaml.dump(overrides, ff)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

失而复得 2025-01-17 13:16:10

只是根本不要使用 yaml 模块来完成此任务,因为您没有做任何它需要做的事情! ;)

f = open("test.yaml", 'r')      
newf = f.read().replace('6', '8')
f.close()

with open('updated_test.yaml', 'w') as ff:
    ff.write(newf)

Just don't use the yaml module for this task at all, as you aren't doing anything what it is needed for ! ;)

f = open("test.yaml", 'r')      
newf = f.read().replace('6', '8')
f.close()

with open('updated_test.yaml', 'w') as ff:
    ff.write(newf)
幻梦 2025-01-17 13:16:10

您的输入是无效的 YAML,因为您无法在第二个 something 之后开始缩进序列。
您的输出也是无效的。

如果您想要类似的内容:

y = 4; 
x = 6 # I wanted to replace this integer to 8  
z = 10

在 YAML 文档中作为多行字符串,并保留您的多行
需要使用ruamel.yaml将字符串指定为文字块标量(使用|)。
由于 x = 6 是字符串的一部分,因此您需要进行字符串替换
更改值。我会使用正则表达式:

import sys
import re
import ruamel.yaml

yaml_str = """\
- sub: |
    y = 4; 
    x = 6 # I wanted to replace this integer to 8  
    z = 10
"""

yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
data = yaml.load(yaml_str)
target = data[0]['sub'] 
new_value = 8
data[0]['sub'] = type(target)(re.sub('x = [0-9]*', f'x = {new_value}', target))
yaml.dump(data, sys.stdout)

它给出:

- sub: |
    y = 4; 
    x = 8 # I wanted to replace this integer to 8  
    z = 10

Your input is invalid YAML, as you cannot start an indented sequence after the second something.
Your output is invalid as well.

If you want something like:

y = 4; 
x = 6 # I wanted to replace this integer to 8  
z = 10

in your YAML document as a multiline string, and preserve the multiple lines you
need to use ruamel.yaml and specify the string as a literal block scalar (using |).
And since x = 6 is part of the string, you need to do a string replacement to
change the value. I would use a regex for that:

import sys
import re
import ruamel.yaml

yaml_str = """\
- sub: |
    y = 4; 
    x = 6 # I wanted to replace this integer to 8  
    z = 10
"""

yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
data = yaml.load(yaml_str)
target = data[0]['sub'] 
new_value = 8
data[0]['sub'] = type(target)(re.sub('x = [0-9]*', f'x = {new_value}', target))
yaml.dump(data, sys.stdout)

which gives:

- sub: |
    y = 4; 
    x = 8 # I wanted to replace this integer to 8  
    z = 10
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文