【问题标题】:How to find a YAML value from Bash using PyYAML如何使用 PyYAML 从 Bash 中查找 YAML 值
【发布时间】:2021-01-22 00:16:12
【问题描述】:

我正在测试在 RHEL7 环境中使用 PyYAML v3.12 解析适度复杂的 YAML 配置文件内容的可行性,方法是为其提供一个密钥并返回密钥对值。查询看起来像这样python my_yaml_search.py key_to_search 并让它打印回value,例如:

所需的 bash 命令:python search_yaml.py $servername

所需响应(仅值,而非键值):myServer14

到目前为止,我已经创建了以下 .py:

import sys
import yaml
key = sys.argv[1]

with open("config.yml") as f:
    try:
        data = yaml.safe_load(f)
        for k, v in data.items():
            if data[k].has_key(key):
                print data[k][v]
    
    except yaml.YAMLError as exc:
        print "Error: key not found in YAML"

config.yml:

---
server:
    servername: myServer14
    filename: testfile.zip
    location: http://test-location/1.com
    repo:
        server_name_fqdn: server.name.fqdn.com
        port: 1234

到目前为止,运行python search_yaml.py $servername 会产生list index out of rangepython search_yaml.py servername 什么也没产生。 我是 Python/PyYAML 的新手,所以我假设我可能错误地将一个变量传递给程序,并且 sys 可能不是我需要的 Python 库,但是我在如何正确地做到这一点上遇到了障碍 -任何输入都会挽救我的理智。

【问题讨论】:

  • 您好 MissCatAssTrophy,欢迎来到 Stack Overflow!你在使用 Python 2 吗?如果是这样,您可以编辑问题以反映这一点吗? (或者更好的是,考虑切换到使用 Python 3,因为 Python 2 现在基本上已经过时了)另外,当我尝试重现您的结果时,我从运行 python2 search_yaml.py servername 得到一个 TypeError。你真的没有输出吗?
  • 如果有多个/嵌套的键匹配输入怎么办?
  • 顺便说一句,对于这个任务来说,一个愚蠢的 grep / awk 可能会比 yaml 解析更快、更容易。
  • 听起来你正在重塑yq。您是否有不想使用现有工具的原因?

标签: python bash shell rhel pyyaml


【解决方案1】:

如果您知道要遍历的所有键,则可以这样做:

import sys
import yaml

key = sys.argv[1]

with open("config.yml") as f:
    data = yaml.safe_load(f)
    n = key.count('.')
    parts = key.split('.')
    res = None
    i = 0
    while i <= n:
        try:
            if not res:
                res = data[parts[i]]
            else:
                res = res[parts[i]]
        except (yaml.YAMLError, KeyError) as exc:
            print ("Error: key not found in YAML")
            res = None
        i = i + 1
    if res:
        print(res)

测试

~# python search_yaml.py server.repo.port
~# 1234

~# python search_yaml.py server.servername
~# myServer14

这可能有错误,我做代码只是为了看看是否可以在没有第三方工具的情况下轻松完成。

适用于 YAML 的 CLI 应用程序

您可能对yq 程序感兴趣。其实有两个同名的程序,一个是用Go实现的,一个是基于Python的(可能比上面的代码复杂):-)

Go-based yq。 您可以从 GitHub 版本安装提供的静态编译的 yq 二进制文件,也可以使用 commercial GetPageSpeed 存储库中的 yum 进行安装,以便以后轻松更新:

sudo yum -y install https://extras.getpagespeed.com/release-latest.rpm
sudo yum -y install yq

那么你可以简单地:

~# yq read config.yml server.servername
~# myServer14

【讨论】:

  • 您,先生,是我们需要但不值得的英雄。您的回答有效;我也会考虑让 YQ 获得批准。谢谢!
猜你喜欢
  • 2019-02-13
  • 2012-07-20
  • 2015-10-23
  • 1970-01-01
  • 2021-04-01
  • 1970-01-01
  • 2012-03-01
  • 2021-05-17
  • 2017-06-29
相关资源
最近更新 更多