我有一个YAML文件,其中包含以下内容:
job_name: "node"
scrape_interval: "15s"
static_configs:
- targets: ['10.10.10.11:8080']
现在如果我执行我的python脚本,它应该使用给定的参数
在YAML文件中追加目标行i.e script.py -ip 10.10.20.30 -p 8181
文件应该如下所示
job_name: "node"
scrape_interval: "15s"
static_configs:
- targets: ['10.10.10.11:8080', '10.10.20.30:8181']
为此我使用下面的python脚本,但是它给出了错误:
#!/usr/bin/python
import os
import yaml
with open('test.yaml', 'ra') as f:
lines = f.readlines()
for i, line in enumerate(lines):
if line.startswith('targets:'):
line[i] = line[i].strip() + 'arg1,arg2\n'
f.seek(0)
for line in lines:
f.write(line)
我该如何解决这个问题?
答案 0 :(得分:1)
您正在导入os
,yaml
(即PyYAML),但您没有使用这些软件包。
您还尝试"编辑" YAML文件好像是非结构化文本,你不应该。相反,您应该加载YAML文件,然后扩展您获得的数据结构,然后将数据结构转储回YAML文件,但不能转移到PyYAML,因为它不支持这种往返而不会丢失信息。
而是使用ruamel.yaml
(免责声明:我是该软件包的作者):
from ruamel.yaml import YAML
yaml = YAML()
yaml.preserve_quotes = True
yaml.indent = 5
yaml.block_seq_indent = 2
ip = '10.10.20.30' # sys.argv[2]
port = 8181 # sys.argv[4]
with open('test.yaml') as f:
data = yaml.load(f)
targets = data['static_configs'][0]['targets']
targets.append(type(targets[0])(str(ip) + ':' + str(port)))
with open('test.yaml', 'w') as fo:
yaml.dump(data, fo)
将写下:
job_name: "node"
scrape_interval: "15s"
static_configs:
- targets: ['10.10.10.11:8080', '10.10.20.30:8181']
仅需要设置属性preserve_quotes
,indent
,block_seq_indent
以使输出与您的输入相匹配。复制类型也是如此
第一个targets
元素。实际上,您的文件中没有引号。
如果有一个更加默认的YAML输出文件,它将加载到相同的数据,你可以这样做:
from ruamel.yaml import YAML
yaml = YAML()
ip = '10.10.20.30' # sys.argv[2]
port = 8181 # sys.argv[4]
with open('test.yaml') as f:
data = yaml.load(f)
data['static_configs'][0]['targets'].append(str(ip) + ':' + str(port))
with open('test.yaml', 'w') as fo:
yaml.dump(data, fo)
请注意,多个条目映射中的键顺序以及YAML文件中的任何注释都将通过上述往返保留。
您当然仍需要从命令行获取IP和端口,并连接值而不是对ip
和port
值进行硬编码。我建议使用标准的python模块argparse
,但要注意大多数应用程序只使用双破折号(--ip
而不是-ip
)来选择长选项。