我有一个小脚本来自动化 YAML 文件中的一些事情。
我读取原始 YAML 文件并将其转换为哈希,然后在修改后将其转储到文件中:
File.open(output_file, "w") do |out|
YAML.dump(modified_hash, out)
end
这很好用,但如果不需要,它会删除字符串周围的双引号。这是有效的 YAML,但看起来不太好。
我可以在每个字符串的末尾添加一个空格来强制使用单引号,但我对此不太满意。有没有办法在字符串周围强制使用双引号?
这工作得很好。我从这里得到的
require 'psych'
ast = Psych.parse_stream DATA.read
# First pass, quote everything
ast.grep(Psych::Nodes::Scalar).each do |node|
node.plain = false
node.quoted = true
node.style = Psych::Nodes::Scalar::DOUBLE_QUOTED
end
# Second pass, unquote keys
ast.grep(Psych::Nodes::Mapping).each do |node|
node.children.each_slice(2) do |k, _|
k.plain = true
k.quoted = false
k.style = Psych::Nodes::Scalar::ANY
end
end
puts ast.yaml
我找到了一个解决方案,这很奇怪,但它有效。
为了强制使用单引号,我遍历了哈希并将"foobar "
(注意空格)附加到每个值。使用后YAML.dump
,我再次打开文件并替换"foobar "
为空字符串。
要强制使用双引号,我发现附加"foo \nbar"
可以完成这项工作。然后,我再次打开文件并"foo \\nbar"
用空字符串替换。奇怪,但有效。
请注意,您可能希望选择比 foobar 不太可能使用的东西。
Here's a Ruby version of @jomo's answer, for anyone's future reference:
def ensure_quotes(h)
h.each do |k, v|
if v.is_a?(Hash)
ensure_quotes(v)
next
end
h[k] = v + "__ensure_quotes__\n "
end
end
def dump_yaml_with_double_quotes(yaml_file)
yaml = YAML.load_file(yaml_file)
File.open(yaml_file, 'w') do |f|
YAML.dump(ensure_quotes(yaml), f, line_width: -1)
end
`sed -i '' "s/__ensure_quotes__[\\]n //g" #{yaml_file}`
end
It loads the YAML from a file, recursively appends the magic quoting string to all the values in a YAML object, then dumps that YAML to the same file, and then uses sed
to remove occurrences of the magic string from the output file.