如何将从文本文件中读取的字符串转储到YAML文件中,而不要使用单引号。

huangapple go评论85阅读模式
英文:

How to dump a string read from a text file into a YAML file without single quotes

问题

我有一个字符串它是一个32字节的`.hex`文件的哈希值它的格式是 `0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075`。我必须从一个文本文件中读取这个字符串然后将它转储到yaml文件中而不带有任何单引号

我在Python中编写的程序是

import yaml

# 指定输入文件的路径
input_file_path = 'output.txt'

# 从输入文件中读取值
with open(input_file_path, 'r') as input_file:
    value = input_file.read().strip()

with open('temp.yaml', 'r') as file:
    yaml_data = yaml.safe_load(file)

yaml_data['DataSecurityContainer']['items'][0] = value

with open('temp.yaml', 'w') as file:
     yaml.dump(yaml_data, file, default_style=None)

期望的yaml文件输出

DataSecurityContainer:
  items:
  - 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075

实际的yaml文件输出

DataSecurityContainer:
  items:
  - '0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075'

我尝试了所有可能的方法来删除这个单引号但它没有正常工作如果有人能告诉我这里的错误是什么我会很感激的
英文:

I have a string which is a 32-byte hash of a .hex file. It is of the format 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075. I have to read this string from a text file and dump it into yaml file without any single quotes.

The program I have written in Python is :

import yaml

# Specify the file path for the input file
input_file_path = 'output.txt'

# Read the value from the input file
with open(input_file_path, 'r') as input_file:
    value = input_file.read().strip()

with open('temp.yaml', 'r') as file:
    yaml_data = yaml.safe_load(file)

yaml_data['DataSecurityContainer']['items'][0] = value

with open('temp.yaml', 'w') as file:
     yaml.dump(yaml_data, file, default_style=None)

Expected outcome in yaml file :

DataSecurityContainer:
  items:
  - 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075

Actual outcome in yaml file:

DataSecurityContainer:
  items:
  - '0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075'

I have tried all possible ways to remove this single quotes but it is not working correctly. Appreciate it if someone could let me know what is the mistake here

答案1

得分: 1

将您的值包装在一个具有自定义表示器的类中。最小示例:

import yaml, sys

class AsHex(str):
  pass

def represent_hex(dumper, data):
  return dumper.represent_scalar("tag:yaml.org,2002:int", data, style="")

yaml.add_representer(AsHex, represent_hex)

yaml.dump({"test": AsHex("0xdeadbeef")}, sys.stdout)

输出:

test: 0xdeadbeef

我们必须生成一个带有!!int标签的标量(这是我们使用的完整形式的简写),因为PyYAML只有在识别到加载值将分配相同标签给它时才会写出不带引号的值。由于您的值是十六进制整数,加载时将为其分配!!int标签,因此我们必须告诉PyYAML,我们生成的标量表示一个!!int

英文:

Wrap your value in a class with a custom representer. Minimal example:

import yaml, sys

class AsHex(str):
  pass

def represent_hex(dumper, data):
  return dumper.represent_scalar("tag:yaml.org,2002:int", data, style="")

yaml.add_representer(AsHex, represent_hex)

yaml.dump({"test": AsHex("0xdeadbeef")}, sys.stdout)

output:

test: 0xdeadbeef

We must generate a scalar with !!int tag (which is a shorthand for the complete form we use) because PyYAML only writes the value without quotes if it recognizes that loading the value will assign the same tag to it. Since your value is a hexadecimal integer, loading will assign the !!int tag to it, so we must tell PyYAML that the scalar we generate represents an !!int.

答案2

得分: 0

我建议你升级到我的 ruamel.yaml。它支持YAML 1.2,可以保留注释、标签等,包括整数的格式:

import sys
import ruamel.yaml

yaml_str = """\
DataSecurityContainer:
  items:
  - 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075   # 作为整数子类加载的标量
"""
    
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

输出结果:

DataSecurityContainer:
  items:
  - 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075   # 作为整数子类加载的标量

如果你检查序列元素,你会发现它是一个特殊类型:

x = data['DataSecurityContainer']['items'][0]
print(x, type(x))

输出结果:

61953922709457582312898796139505834842512090556466629792920972610962764374133 <class 'ruamel.yaml.scalarint.HexInt'>

要创建所需的输出,你需要创建一个 HexInt 实例,可以从从输入文件中读取的字符串构造的整数创建:

import sys
from pathlib import Path
import ruamel.yaml

value = '0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075'
data = dict(DataSecurityContainer=dict(items=[ ruamel.yaml.scalarint.HexInt(int(value, 0)) ]))

path = Path('temp.yaml')
yaml = ruamel.yaml.YAML()
yaml.dump(data, path)
sys.stdout.write(path.read_text())

输出结果:

DataSecurityContainer:
  items:
  - 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075

从文件中读取字符串 value 并通过加载包含YAML文档的文件创建 data 是非常简单的,唯一的 '魔法' 在于将 value 转换为 HexInt()(并且放弃了长时间过时的PyYAML)。

英文:

I recommend you upgrade to my ruamel.yaml. It supports YAML 1.2, can preserve comments, tags, etc, including the formatting
of an integer:

import sys
import ruamel.yaml

yaml_str = &quot;&quot;&quot;\
DataSecurityContainer:
  items:
  - 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075   # scalar loaded as integer subclass
&quot;&quot;&quot;
    
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

which gives:

DataSecurityContainer:
  items:
  - 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075   # scalar loaded as integer subclass

if you inspect that sequence element, you see that it is a special type:

x = data[&#39;DataSecurityContainer&#39;][&#39;items&#39;][0]
print(x, type(x))

printing:

61953922709457582312898796139505834842512090556466629792920972610962764374133 &lt;class &#39;ruamel.yaml.scalarint.HexInt&#39;&gt;

To create the required output, you create a HexInt instance, which you can do from the integer constructed from the string
you would read from the input file:

import sys
from pathlib import Path
import ruamel.yaml

value = &#39;0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075&#39;
data = dict(DataSecurityContainer=dict(items=[ ruamel.yaml.scalarint.HexInt(int(value, 0)) ]))

path = Path(&#39;temp.yaml&#39;)
yaml = ruamel.yaml.YAML()
yaml.dump(data, path)
sys.stdout.write(path.read_text())

which gives:

DataSecurityContainer:
  items:
  - 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075

And it is trivial to read the string value from a file and create data by loading a file containing a YAML document,
the only 'magic' is in converting value to a HexInt() (and dropping the long outdated PyYAML).

huangapple
  • 本文由 发表于 2023年7月13日 21:39:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76680039.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定