【问题标题】:Extract distinct values from yaml从 yaml 中提取不同的值
【发布时间】:2020-03-10 03:31:47
【问题描述】:

我需要使用python脚本从下面的文件中提取--my_dataset--my_table--s3_temp_path

我的文件:

▶ cat my_datasets/my_file.yml
__global__:
  role: myrole
  contact: sam@user.com

__default__:
  cc_policy: VERY_NEW
  act_num: 16384
  react_num: 16384
  with_start: 1
  where_to: my_file.log
  class: myClass
  my_arguements: >-
    -Dmy.num.1=4096
    -Dmy.num.2=true
    -Dmy.num.3=fgcd
  is_it: true
  if_not: false
  compure: dc1
  env: test
  my_compute: res-dc
  config: /my/file/config

first_adhoc:
  my_space: my_transfer
  doodle: my_transfer.tar.gz
  jar: my_transfer.jar
  my_dir: "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10/dir11:my-deploy"
  my_arguments: >-
    m.big.class
    --sdrs
    --tz UTC
    --env test
    --my_dataset my_analytics
    --my_table onboarding_client_events
    --current_date 2020-09-22
    --my_project my_aws_project
    --s3_temp_path s3://test-wierd/
    --my_key_json dir1/dir2/dir3/dir4/keys.json
    --my_auth_file dir1/dir2/dir3/dir4/gcp/my_new.yml
    --my_proxy example.com:9999
    --write_mode write
    --update_option option1 option2

first_cron:
  my_space: my_transfer
  doodle: my_transfer.tar.gz
  jar: my_transfer.jar
  my_dir: "dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10/dir11:my-deploy"
  my_arguments: >-
    m.big.class
    --sdrs
    --tz UTC
    --env test
    --my_dataset my_analytics
    --my_table i_wish
    --current_date 2020-09-22
    --my_project my_aws_project
    --s3_temp_path s3://test-wierd/
    --my_key_json dir1/dir2/dir3/dir4/keys.json
    --my_auth_file dir1/dir2/dir3/dir4/gcp/my_new.yml
    --my_proxy example.com:9999
    --write_mode write
    --update_option option1 option2
  cron_schedule: "* * 4 * *"

我在 base_path 中有很多像我上面提到的文件,从我需要获取 --my_dataset--my_table--s3_temp_path 的所有文件中。

以下是我到目前为止的时间。我能够使用 my_file.yaml 递归提取所有文件,但我无法提取上述 distinct 值。

我的脚本:

import fnmatch
import os
import re
import yaml


user_path = os.path.expanduser('~')
source_path = user_path + "/where/are/"
base_path = source_path + "/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10"


def find(pattern, base_path):
    results = []
    for root, dirs, files in os.walk(base_path):
        for name in files:
            if fnmatch.fnmatch(name, pattern):
                results.append(os.path.join(root, name))

    for result in results:
        stream = open(result, 'r')
        dictionary = yaml.load(stream)
        for key, value in dictionary.items():
            res = dict((k, dictionary[k]) for k in ['my_dataset', 'my_table', 's3_temp_path' ] 
                                        if k in dictionary) 
            print (key + " : " + str(value))

print find('my_file.yml', base_path)

当前结果:

▶ python myWork.py
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
None

预期结果:

{"my_dataset": "my_analytics", "my_table": "i_wish", "s3_temp_path": "s3://test-wierd/"}

【问题讨论】:

  • 如您所见,您需要的键不存在于字典的根级别。它们存在于 my_arguments 中,而 my_arguments 位于另一个键本身内。是my_arguments 还是my_arguements ?.
  • 我正在尝试提取my_arguments
  • 你的代码中没有这样做。
  • 如果我这样做,我仍然会得到一个空字典 ``` res = dict((k, dictionary[k]) for k in ['arguments'] if k in dictionary) # print (key + " : " + str(value)) 打印分辨率 ``

标签: python python-3.x dictionary yaml python-2.x


【解决方案1】:

您的代码给人的印象是您只是随意编写了一些行,根本没有考虑您尝试导航的结构。

首先,让我们看看您的值在哪里:它们包含在一个长折叠标量中。这将被加载到 Python 中的字符串中,您不能通过它们的名称直接查询值,因为 YAML 不理解这些是 cmdline 参数。因此,让我们编写一个从该字符串中提取值的函数:

def get_cmdline_arg(name, cmdline):
  found = False
  for item in cmdline.split():
    if found: return item
    # if the current item is the searched name, the next item will be
    # its value
    found = (item == name)
  return "<not found>"

现在,让我们看看如何从结构中获取my_arguments 字符串。您的 YAML 在其根级别有四个键:__global____default__first_adhocfirst_cron。您要搜索的数据位于 first_adhocfirst_cron 中,所以让我们从迭代这两个值开始(从代码中加载的 dictionary 值开始):

for k in ['first_adhoc', 'first_cron']:
  arguments = dictionary[k]['my_arguments']

现在我们有了my_arguments 值,我们只需要获取您的参数值:

  res = {}
  for name in ['my_dataset', 'my_table', 's3_temp_path']:
    res[name] = get_cmdline_arg('--' + name, arguments)
  print(k + ": " + str(res))

【讨论】:

    【解决方案2】:

    感谢您的回复,我可以通过编写以下代码来解决此问题。

    import os
    import yaml
    tbl = []
    def getNames(pattern, base_path):
        rsls = []
        for root, dirs, files in os.walk(base_path):
            for name in files:
                if fnmatch.fnmatch(name, pattern):
                    rsls.append(os.path.join(root, name))
        for rsl in rsls:
            stream = open(rsl, 'r')
            dictionary = yaml.load(stream)
            for key, value in dictionary.items():
                if 'my_arguments' in value:
                    arg_val = value['my_arguments']
                    tname_fractions = []
                    for col in col_names:
                        col_val = arg_val.split(col)[1].strip().split()[0]
                        tname_fractions.append(col_val)
                    tbl_nm = ','.join(tname_fractions)
                    tbls.append(tbl_nm)
                    utl = list(set(tbls))
    
        return utl
    

    【讨论】:

    • 感谢您的回复,我同意您的观点,我没有考虑太多。我刚开始学习 Python。
    猜你喜欢
    • 2021-02-25
    • 2016-11-10
    • 2019-01-06
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 2021-09-24
    相关资源
    最近更新 更多