尝试获取YAML文件中的所有路径

尝试获取YAML文件中的所有路径,yaml,pyyaml,ruamel.yaml,Yaml,Pyyaml,Ruamel.yaml,我有一个输入YAML文件(test.yml),如下所示: # sample set of lines foo: x: 12 y: hello world ip_range['initial']: 1.2.3.4 ip_range[]: tba array['first']: Cluster1 array2[]: bar 源包含一些键的方括号(可能为空) 我试图获得文件中所有路径的逐行列表,理想情况下如下: foo.x: 12 foo.y: hello world foo.

我有一个输入YAML文件(test.yml),如下所示:

# sample set of lines
foo:
  x: 12
  y: hello world
  ip_range['initial']: 1.2.3.4
  ip_range[]: tba
  array['first']: Cluster1

array2[]: bar
源包含一些键的方括号(可能为空)

我试图获得文件中所有路径的逐行列表,理想情况下如下:

foo.x: 12
foo.y: hello world
foo.ip_range['initial']: 1.2.3.4
foo.ip_range[]: tba
foo.array['first']: Cluster1
array2[]: bar

我使用了库和
yaml路径
CLI,但无法获得所需的输出。试一试:

yaml-paths -m -s =foo -K test.yml
产出:

foo.x
foo.y
foo.ip_range\[\'initial\'\]
foo.ip_range\[\]
foo.array\[\'first\'\]
每个路径位于一行上,但输出包含所有转义字符(\)。修改调用以删除-m选项(“展开匹配的父节点”)修复了该问题,但输出不是每行一条路径:

yaml-paths -s =foo -K test.yml
给出:

foo: {"x": 12, "y": "hello world", "ip_range['initial']": "1.2.3.4", "ip_range[]": "tba", "array['first']": "Cluster1"}

你知道我怎么能在没有逃逸符的情况下,在每个路径入口上得到一行吗?我想知道ruamel模块中是否有用于路径查询的内容?

您的“路径”只不过是该模块的键(可能还有索引)的连接字符串表示 YAML文档中的映射(以及可能的序列)

可以通过递归函数从YAML加载的数据生成:

import sys
import ruamel.yaml

yaml_str = """\
# sample set of lines
foo:
  x: 12
  y: hello world
  ip_range['initial']: 1.2.3.4
  ip_range[]: tba
  array['first']: Cluster1

array2[]: bar
"""

def pathify(d, p=None, paths=None, joinchar='.'):
    if p is None:
        paths = {}
        pathify(d, "", paths, joinchar=joinchar)
        return paths
    pn = p
    if p != "":
        pn += '.'
    if isinstance(d, dict):
        for k in d:
            v = d[k]
            pathify(v, pn + k, paths, joinchar=joinchar)
    elif isinstance(d, list):
        for idx, e in enumerate(d):
            pathify(e, pn + str(idx), paths, joinchar=joinchar)
    else:
        paths[p] = d


yaml = ruamel.yaml.YAML(typ='safe')
paths = pathify(yaml.load(yaml_str))

for p, v in paths.items():
    print(f'{p} -> {v}')
其中:

foo.x -> 12
foo.y -> hello world
foo.ip_range['initial'] -> 1.2.3.4
foo.ip_range[] -> tba
foo.array['first'] -> Cluster1
array2[] -> bar
您的“路径”只不过是数据的键(可能还有索引)的连接字符串表示 YAML文档中的映射(以及可能的序列)

可以通过递归函数从YAML加载的数据生成:

import sys
import ruamel.yaml

yaml_str = """\
# sample set of lines
foo:
  x: 12
  y: hello world
  ip_range['initial']: 1.2.3.4
  ip_range[]: tba
  array['first']: Cluster1

array2[]: bar
"""

def pathify(d, p=None, paths=None, joinchar='.'):
    if p is None:
        paths = {}
        pathify(d, "", paths, joinchar=joinchar)
        return paths
    pn = p
    if p != "":
        pn += '.'
    if isinstance(d, dict):
        for k in d:
            v = d[k]
            pathify(v, pn + k, paths, joinchar=joinchar)
    elif isinstance(d, list):
        for idx, e in enumerate(d):
            pathify(e, pn + str(idx), paths, joinchar=joinchar)
    else:
        paths[p] = d


yaml = ruamel.yaml.YAML(typ='safe')
paths = pathify(yaml.load(yaml_str))

for p, v in paths.items():
    print(f'{p} -> {v}')
其中:

foo.x -> 12
foo.y -> hello world
foo.ip_range['initial'] -> 1.2.3.4
foo.ip_range[] -> tba
foo.array['first'] -> Cluster1
array2[] -> bar

虽然Anthon的回答肯定会产生您想要的输出,但我认为您的问题是关于如何获得
yaml path
命令以产生所需的输出。我将回答最初的问题

从3.5.0版开始,项目的
yaml路径
命令支持一个
--noescape
选项,该选项从输出中删除转义符号。使用输入文件和新选项,您可能会发现此输出更符合您的喜好:

$ yaml-paths --nofile --expand --keynames --noescape --values --search='=~/.*/' test.yml
foo.x: 12
foo.y: hello world
foo.ip_range['initial']: 1.2.3.4
foo.ip_range[]: tba
foo.array['first']: Cluster1
array2[]: bar
注:

  • 使用
    --values
    选项包括每个YAML路径的值
  • 出于兴趣,我更改了
    --search
    表达式,以匹配输入文件中的每个节点,而不仅仅是“foo”数据
  • 默认输出(不设置
    --noescape
    )生成YAML路径,该路径可用作其他YAML路径解析器和处理器的直接输入;设置
    --noescape
    会更改此设置,以呈现可能无法作为下游YAML路径输入的人性化路径

  • 免责声明:我是yamlpath项目的作者。如果您遇到问题或对此有疑问,请访问项目的GitHub项目站点,并通过问题(bug和功能请求)或讨论(问题)与我联系。谢谢大家!

    虽然Anthon的回答肯定会产生您想要的输出,但我认为您的问题是关于如何获得
    yaml path
    命令以产生所需的输出。我将回答最初的问题

    从3.5.0版开始,项目的
    yaml路径
    命令支持一个
    --noescape
    选项,该选项从输出中删除转义符号。使用输入文件和新选项,您可能会发现此输出更符合您的喜好:

    $ yaml-paths --nofile --expand --keynames --noescape --values --search='=~/.*/' test.yml
    foo.x: 12
    foo.y: hello world
    foo.ip_range['initial']: 1.2.3.4
    foo.ip_range[]: tba
    foo.array['first']: Cluster1
    array2[]: bar
    
    注:

  • 使用
    --values
    选项包括每个YAML路径的值
  • 出于兴趣,我更改了
    --search
    表达式,以匹配输入文件中的每个节点,而不仅仅是“foo”数据
  • 默认输出(不设置
    --noescape
    )生成YAML路径,该路径可用作其他YAML路径解析器和处理器的直接输入;设置
    --noescape
    会更改此设置,以呈现可能无法作为下游YAML路径输入的人性化路径

  • 免责声明:我是yamlpath项目的作者。如果您遇到问题或对此有疑问,请访问项目的GitHub项目站点,并通过问题(bug和功能请求)或讨论(问题)与我联系。谢谢大家!

    自2006年9月以来,YAML.org推荐的YAML文件扩展名为
    .YAML
    。自2006年9月以来,YAML.org推荐的YAML文件扩展名为
    .YAML