Copy content from one YAML to another YAML after comparison of keys

匆匆过客 提交于 2019-12-12 02:08:12

问题


I have a use case where I need to pick key:value pairs from a new YAML file. Check whether that key exists in old YAML file and if it does copy the value and set it in new YAML file.
Also if that key does not exist in old file then ask the user.

Code:

copyfile('all.isv', '/home/ubuntu/tmp/deploy/all')
with open("/home/ubuntu/ansible-environments/aws/lp/all", 'r') as f1:
    try:
        oldvars = yaml.load(f1)
        with open("/home/ubuntu/tmp/deploy/all", 'rw') as f2:
                newvars = yaml.load(f2)
                for key,value in newvars.items():
                        print key, ":", value
                        if key in f1:
                                value =  oldvars.items(value)
                                print key,value
                                f2.write(value)
                        else:
                                value = raw_input("Enter the value ")

It's not working. Not able to understand how to check the key in old file and write value for that key in new file.

New File :

# Enter the release and build you wish to deploy
release: "4.0"
build: "4_0_178"
ems_release: "4.0"
ems_build: "4_0_982"
build_type: "gold_master"

# The name prefix is synonymous with the stack (i.e. pdx02-cloud-prod)
name_prefix: syd01-devops-test

# The deployment type is one of: [ test | trial | dev | prod ]
deployment_type: test
# deployment_url is typically the same value as deployment type unless it is a premium deployment.
# In that case deployment_type is set to prod and deployment_url is either dev, trial or test
deployment_url: "{{ deployment_type }}"
some_new_var: hello

Old File :

# Enter the release and build you wish to deploy
release: "4.0"
build: "4_0_178"
ems_release: "4.0"
ems_build: "4_0_999"
build_type: test_build

# The name prefix is synonymous with the stack (i.e. pdx02-cloud-prod)
name_prefix: syd01-devops-deepali

# The deployment type is one of: [ test | trial | dev | prod ]
deployment_type: trial
# deployment_url is typically the same value as deployment type unless it is a premium deployment.
# In that case deployment_type is set to prod and deployment_url is either dev, trial or test
deployment_url: "{{ deployment_type }}"

Expected: File generated using two files(old and new)

# Enter the release and build you wish to deploy
    release: "4.0"
    build: "4_0_178"
    ems_release: "4.0"
    ems_build: "4_0_999"
    build_type: test_build

    # The name prefix is synonymous with the stack (i.e. pdx02-cloud-prod)
    name_prefix: syd01-devops-deepali

    # The deployment type is one of: [ test | trial | dev | prod ]
    deployment_type: trial
    # deployment_url is typically the same value as deployment type unless it is a premium deployment.
    # In that case deployment_type is set to prod and deployment_url is either dev, trial or test
    deployment_url: "{{ deployment_type }}"
    some_new_var: Value provided by user as input

回答1:


That is invalid Python, your try doesn't have a matching except. Apart from that it is not necessary to open the second file in the context of the with statement that you use for reading in the "old" file. Therefore start with:

import ruamel.yaml

copyfile('all.isv', '/home/ubuntu/tmp/deploy/all')
with open("/home/ubuntu/ansible-environments/aws/lp/all", 'r') as f1:
    oldvars = ruamel.yaml.round_trip_load(f1)

You cannot open a YAML file for reading and writing, therefore just read it (and opening for reading and writing of a file is done with 'r+' not with 'rw'):

with open("/home/ubuntu/tmp/deploy/all", 'r') as f2:
    newvars = ruamel.yaml.round_trip_load(f2)

After that continue unindented and update newvars from oldvars if appropriate:

for key in newvars:
    if key in oldvars:
        # this copies the value from the old file if the key exists in there
        value =  oldvars[key] 
    else:
        # ask the user for a new value
        value = raw_input("Enter the value ")
    # update the value in newvars
    newvars[key] = value
# and write the update mapping back
with open("/home/ubuntu/tmp/deploy/all", 'w') as f2:
     ruamel.yaml.round_trip_dump(newvars, f2)

Combining that and naming your files old.yaml and new.yaml and answering the prompt with 'abcd':

import sys
import ruamel.yaml

with open('new.yaml') as fp:
    newvars = ruamel.yaml.round_trip_load(fp)
with open('old.yaml') as fp:
    oldvars = ruamel.yaml.round_trip_load(fp)
for key in newvars:
    if key in oldvars:
        # this copies the value from the old file if the key exists in there
        value =  oldvars[key]
    else:
        # ask the user for a new value
        value = raw_input("Enter the value ")
    # update the value in newvars
    newvars[key] = value
ruamel.yaml.round_trip_dump(newvars, sys.stdout)

gives you:

Enter the value abcd
# Enter the release and build you wish to deploy
release: '4.0'
build: '4_0_178'
ems_release: '4.0'
ems_build: '4_0_999'
build_type: test_build
# The name prefix is synonymous with the stack (i.e. pdx02-cloud-prod)
name_prefix: syd01-devops-deepali

# The deployment type is one of: [ test | trial | dev | prod ]
deployment_type: trial
# deployment_url is typically the same value as deployment type unless it is a premium deployment.
# In that case deployment_type is set to prod and deployment_url is either dev, trial or test
deployment_url: '{{ deployment_type }}'
some_new_var: abcd

Please note that:

  • this only runs on Python 2.7
  • for scalars that do not need them quotes are dropped
  • I did not try to include the four space indentation of your output past the first line.


来源:https://stackoverflow.com/questions/37661712/copy-content-from-one-yaml-to-another-yaml-after-comparison-of-keys

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!