【问题标题】:modify line content using python使用python修改行内容
【发布时间】:2018-10-19 21:56:45
【问题描述】:

我需要使用 python 代码修改 YAML 文件中的一行。我要修改的是- {tokens开头的那一行:

rpc: sync
nodes_dir: /data/tmp
list_provider:
- class_name: org.apache.test
  parameters:
  - {tokens: '{{ printf "%s/%s/%s/nodes" (env "var1") (env "var2") (env "var3") | key}}'}

我想达到这个结果:

rpc: sync
nodes_dir: /data/tmp
list_provider:
- class_name: org.apache.test
  parameters:
  - {tokens: ''}

我使用的是 python 的 YAML 加载器,因为它不允许文件中的特殊字符。

with open('test.yaml', 'r') as file:
    data = yaml.load(file)
print(data)
data["list_provider"][0]['parameters'][0]['tokens'] = str(list_var)
with open("test.yaml", "w") as f:
    yaml.dump(data, f)

我无法使用 ruamel.yaml 模块,因为我无法在我的机器上安装新软件包。如何使用 PyYAML 实现这一点?

【问题讨论】:

  • 感谢您的编辑。我正在使用 python 3.6.4 和 pyyaml 3.12 以及您的示例 yaml 和您提供的代码来测试您的代码。我已经用'' 替换了list_var,因为我不知道那里发生了什么。我得到了想要的输出?我是否使用错误的版本进行测试?
  • 我用的是python 2.7.13,这个版本不行
  • 您收到什么消息错误?或者,期望的结果和实际的结果有什么区别?
  • @brandizzi 如果你运行该代码,你会得到一个NameError: name 'list_var' is not defined
  • 错误消息:yaml.scanner.ScannerError:在扫描下一个令牌时发现字符'%'不能在“/tmp/test.yaml”中启动任何令牌,第 361 行,第 32 列跨度>

标签: python sed pyyaml


【解决方案1】:

我不确定我是否正确理解了您的观点,但我会使用纯 python 方式:

import re

r = re.compile(r'^ *- {tokens:.*}$')

modified_content = ''
with open('file.yaml', 'r') as fd:
    for line in fd.readlines():
        if r.match(line):
            line = re.sub(r'tokens:.*}$', "tokens: ''}", line)
        modified_content += line

with open('file.yaml', 'w') as fd:
    fd.write(modified_content)

【讨论】:

  • 您的代码假定 YAML 没有包装令牌 '{{ printf ....}}',如果该令牌变得更长,它很容易被转储到多行。
【解决方案2】:

您的程序几乎可以得到您需要的输出,您只需将str(list_var)(因为这会引发错误)更改为''

import sys
import yaml

with open('test.yaml', 'r') as file:
    data = yaml.load(file)
print(data)
data["list_provider"][0]['parameters'][0]['tokens'] = ''

yaml.dump(data, sys.stdout)

输出:

list_provider:
- class_name: org.apache.test
  parameters:
  - {tokens: ''}
nodes_dir: /data/tmp
rpc: sync

YAML 文档根目录的映射的键顺序不会保留在 PyYAML 中。但除此之外,这正是您要求的输出。

【讨论】:

  • 当我使用您发布的相同代码时出现以下错误。我正在使用 python 2.7.13。 yaml.scanner.ScannerError:在扫描下一个标记时发现字符“%”无法在“/tmp/test.yaml”中启动任何标记,第 361 行,第 32 列
  • @wasay 您不仅应该使用代码,还应该使用正确的 YAML 文件。您的 YAML 输入没有 361 行,因此您正在使用不正确的 test.yaml 进行测试(或者您应该发布一个 new 问题,其中包含其他 test.yaml 的相关部分,第 361 行和上下文,包括)。
猜你喜欢
  • 1970-01-01
  • 2011-08-23
  • 2021-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多