在yaml文件python中更改<test>

时间:2016-05-18 12:37:20

标签: python tags yaml

我必须在yaml文件中替换这些标签 以前替换的数据存储在列表中 我有这个YAML文件

vagrantfile:    
    target: local
    vm:
        provider:
            local:
                box: puphpet/ubuntu1404-x<BITS> # MEERKEUZE: 32 OF 64, STANDAARD 64
                box_url: puphpet/ubuntu1404-x<BITS> # MEERKEUZE: 32 OF 64, STANDAARD 64
                box_version: '0'
                chosen_virtualizer: <virtualiser>  # MEERKEUZE: virtualbox OF vmware, STANDAARD 64
                virtualizers:
                    virtualbox:
                        modifyvm:
                            natdnshostresolver1: false
                        showgui: 0
                    vmware:
                        numvcpus: 1
                    parallels:
                        use_linked_clone: 0
                        check_guest_tools: 0
                        update_guest_tools: 0
                machines:
                    vflm_7orc03npv15g:
                        id: <ID> # STRING
                        hostname: <HOSTNAME> # STRING
                        network:
                            private_network: <IP-ADDRESS> #lOKAAL IP, STANDARAARD 192.168.50.101
                            forwarded_port:
                                hon1d:
                                    host: '80'
                                    guest: '80'
                        memory: '<MEGABYTES>' # AANTAL, STANDAARD VEELVOUD VAN 1024
                        cpus: '<CORES>' # AANTAL CPUS, STANDAARD AANTAL CORES - 1, NIET HOGER DAN AANTAL CORES

如何更改这些标签?

3 个答案:

答案 0 :(得分:1)

你应该在YAML级别执行此操作,只是为了确保如果你的替换强制引用生成的字符串,这实际发生了。例如。如果<ID>需要替换@abc之类的内容,则YAML文件中的实际行需要变为

id: '@abc'

而不是

id: '@abc' 

保留@。有几个这样的警告,所以替换字符串级别不是一个好主意。

你可以这样做:

import sys
import ruamel.yaml

yaml_str = """\
vagrantfile:
    target: local
    vm:
        provider:
            local:
                box: puphpet/ubuntu1404-x<BITS> # MEERKEUZE: 32 OF 64, STANDAARD 64
                box_url: puphpet/ubuntu1404-x<BITS> # MEERKEUZE: 32 OF 64, STANDAARD 64
                box_version: '0'
                chosen_virtualizer: <virtualiser>  # MEERKEUZE: virtualbox OF vmware, STANDAARD 64
                virtualizers:
                    virtualbox:
                        modifyvm:
                            natdnshostresolver1: false
                        showgui: 0
                    vmware:
                        numvcpus: 1
                    parallels:
                        use_linked_clone: 0
                        check_guest_tools: 0
                        update_guest_tools: 0
                machines:
                    vflm_7orc03npv15g:
                        id: <ID> # STRING
                        hostname: <HOSTNAME> # STRING
                        network:
                            private_network: <IP-ADDRESS> #lOKAAL IP, STANDARAARD 192.168.50.101
                            forwarded_port:
                                hon1d:
                                    host: '80'
                                    guest: '80'
                        memory: '<MEGABYTES>' # AANTAL, STANDAARD VEELVOUD VAN 1024
                        cpus: '<CORES>' # AANTAL CPUS, STANDAARD AANTAL CORES - 1, NIET HOGER DAN AANTAL CORES
"""


def replace(data, values):
    def do_one(data, values):
        if isinstance(data, dict):
            for k in data:
                data[k] = do_one(data[k], values)
            return data
        elif isinstance(data, list):
            for idx, elem in enumerate(data):
                data[idx] = do_one(elem, values)
            return data
        elif isinstance(data, str):
            for k in values:  # full match
                if data == k:
                    return values[k]
            if '<' in data and '>' in data:
                for k in values:
                    data = data.replace(k, str(values[k]))
                return data


    expanded = { ('<' + k + '>'): v for (k, v) in values.iteritems()}
    do_one(data, expanded)

data = ruamel.yaml.round_trip_load(yaml_str)

replace(data, {
    'BITS': 64,
    'virtualiser': 'virtualbox',
    'HOSTNAME': 'localhost',
    'IP-ADDRESS': '192.168.0.1',
    'ID': '@abc',
    'MEGABYTES': 2048,
    'CORES': 8,
    })

ruamel.yaml.round_trip_dump(data, stream=sys.stdout, indent=4)

会给你:

vagrantfile:
    target:
    vm:
        provider:
            local:
                box: puphpet/ubuntu1404-x64     # MEERKEUZE: 32 OF 64, STANDAARD 64
                box_url: puphpet/ubuntu1404-x64     # MEERKEUZE: 32 OF 64, STANDAARD 64
                box_version:
                chosen_virtualizer: virtualbox     # MEERKEUZE: virtualbox OF vmware, STANDAARD 64
                virtualizers:
                    virtualbox:
                        modifyvm:
                            natdnshostresolver1:
                        showgui:
                    vmware:
                        numvcpus:
                    parallels:
                        use_linked_clone:
                        check_guest_tools:
                        update_guest_tools:
                machines:
                    vflm_7orc03npv15g:
                        id: '@abc' # STRING
                        hostname: localhost  # STRING
                        network:
                            private_network: 192.168.0.1  #lOKAAL IP, STANDARAARD 192.168.50.101
                            forwarded_port:
                                hon1d:
                                    host:
                                    guest:
                        memory: 2048          # AANTAL, STANDAARD VEELVOUD VAN 1024
                        cpus: 8         # AANTAL CPUS, STANDAARD AANTAL CORES - 1, NIET HOGER DAN AANTAL CORES

请注意:

  • 保留评论
  • cpusmemory的值是整数,而不是字符串
  • 根据需要正确引用id的值。

上述用途ruamel.yaml:免责声明我是该套餐的作者。您也可以使用PyYAML,但是您将失去评论,您需要将自己限制在YAML 1.1标准(从2005年开始)而不是YAML 1.2标准(从2009年开始)

答案 1 :(得分:0)

可能最容易使用pyyaml。例如。设置cpus值:

import yaml
foo = yaml.load(open('file.yml', 'r'))
foo['vagrantfile']['vm']['provider']['local']['machines']['vflm_7orc03npv15g']['memory'] = 'bar'
yaml.dump(foo, open('out.yml', 'w'))

唯一的问题是你会以这种方式丢失评论。

答案 2 :(得分:0)

您可以将yaml转换为字符串模板,并使用字符串格式来实现此

template = """vagrantfile:    
    target: local
    vm:
        provider:
            local:
                box: puphpet/ubuntu1404-x%(BITS)s # MEERKEUZE: 32 OF 64, STANDAARD 64
                box_url: puphpet/ubuntu1404-x%(BITS)s # MEERKEUZE: 32 OF 64, STANDAARD 64
                box_version: '0'
                chosen_virtualizer: %(virtualiser)s  # MEERKEUZE: virtualbox OF vmware, STANDAARD 64
                virtualizers:
                    virtualbox:
                        modifyvm:
                            natdnshostresolver1: false
                        showgui: 0
                    vmware:
                        numvcpus: 1
                    parallels:
                        use_linked_clone: 0
                        check_guest_tools: 0
                        update_guest_tools: 0
                machines:
                    vflm_7orc03npv15g:
                        id: %(ID)s # STRING
                        hostname: %(OSTNAME)s # STRING
                        network:
                            private_network: %(IP-ADDRESS)s #lOKAAL IP, STANDARAARD 192.168.50.101
                            forwarded_port:
                                hon1d:
                                    host: '80'
                                    guest: '80'
                        memory: '%(MEGABYTES)s' # AANTAL, STANDAARD VEELVOUD VAN 1024
                        cpus: '%(CORES)s' # AANTAL CPUS, STANDAARD AANTAL CORES - 1, NIET HOGER DAN AANTAL CORES"""


replaced = template % {"BITS": "some value", "virtualiser": "something", "ID": 2412, "OSTNAME": "OS name", "IP-ADDRESS": "some ip", "MEGABYTES": 100, "CORES": 16}