在yaml文件python中更改<TEST>

2024-06-06 22:30:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我必须在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

我能做些什么来改变这些标签?在


Tags: 文件ofboxlocal标签coresbitsvmware
3条回答

可能最容易使用pyyaml。E、 g.要设置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'))

唯一的问题是这样你会失去评论。在

您应该在YAML级别执行此操作,以确保如果您的替换强制引用结果字符串,则会发生这种情况。E、 如果您的<ID>需要被@abc之类的东西替换,那么YAML文件中的实际行需要变成

id: '@abc'

而不是

^{pr2}$

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

您可以:

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的值被正确引用。在

上面使用^{}:免责声明我是该包的作者。你可以用PyYAML做同样的事情,但是你会失去评论,你需要限制自己使用yaml1.1标准(从2005年开始),而不是yaml1.2标准(从2009年开始)

您可以将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}

相关问题 更多 >