假设您有一个模板YAML文件:
foo:
bar: {%VARIABLE%}
,并希望bar
的值是字符串化的JSON?例如:
foo:
bar: '{ "hey": "there" }'
就我而言,JSON位于文件中,因此我正在这样做:
VAR=$(cat my.json)
sed -i '' "s|{%VARIABLE%}|'$VAR'|g" foo.yaml
但是如果您将换行符保留在JSON中,sed会抱怨。
如果我使用cat my.json | tr -d '\n'
删除换行符,则提取我的JSON的程序会显示JSON中的私钥无效。
执行此操作的正确方法是什么?
答案 0 :(得分:1)
我建议改用perl
,它比sed
更健壮,并且还可以编写一些单行代码,例如:
VAR=$(<my.json)
perl -i.bak -wpe "s|{%VARIABLE%}|'$VAR'|g" foo.yaml
(经过下面的文件my.json
的测试)
{ "hey" : "there",
"status" : "ok" }
最后,请注意,如果.json
文件包含$和@之类的字符,它们在替换字符串中可能具有特殊含义,那么值得依靠Perl的引用运算符q{}
:
perl -i.bak -wpe "my \$x=q{$VAR}; s|{%VARIABLE%}|'\$x'|g" foo.yaml
或者:
perl -i.bak -wpe "my \$x='$VAR'; s|{%VARIABLE%}|'\$x'|g" foo.yaml
答案 1 :(得分:1)
您所拥有的没有YAML文件,甚至没有模板YAML文件,
因为这是无效的YAML,所以:(流)映射开始指示符def customer_profiles(country, name):
print("{},{}".format(name, country))
customer_profiles(**{"gender" : "male", "name" : "David" , "country" : "USA"})
后没有
键值对。
您所拥有的是一个YAML文件的模板,该模板使用
jinja2模板,并且有Traceback (most recent call last):
File "luggage.py", line 12, in <module>
customer_profiles(**{"gender" : "male", "name" : "David" , "country" : "USA"})
TypeError: customer_profiles() got an unexpected keyword argument 'gender'
的插件可用于
完全更新那种模板(实际上通常要多一些)
比您的复杂)。该插件将模板转换为有效的YAML
文件,然后可以使用Python安全地加载,更新和转储文件。
它的主要优点是可以将值节点设置为表示为 文字样式标量,并且无论哪种JSON都没有问题 扔掉它,因为您的字符串化JSON至少需要转义 的引号(使用双引号时还可以使用反斜杠)。
{
给出:
ruamel.yaml
通常,模板的non-jinja2部分被编辑为YAML,在您需要使用import sys
import ruamel.yaml
yaml_str = """\
foo:
bar: {%VARIABLE%}
"""
json_str = """\
{
"hey": "there's cake"
}
"""
yaml = ruamel.yaml.YAML(typ='jinja2')
data = yaml.load(yaml_str)
data['foo']['bar'] = ruamel.yaml.scalarstring.LiteralScalarString(json_str)
del data['foo'].ca._items['bar']
yaml.dump(data, sys.stdout)
的情况下,
否则,%VARIABLE%将会显示在输出中的注释中。
我故意更改了JSON中的值以包含单引号。将其包括在您的示例中 您需要执行的输出:
foo:
bar: |
{
"hey": "there's cake"
}
尽管使用不支持YAML的工具(例如
del
,正确处理空行的多行JSON否
不重要的。通过将元素插入为
文字样式标量,但这必须使用适当的解析器来完成,
那样可以例如遇到第一行时采取适当的措施
缩进量小于第二个缩进量的JSON,等等。