简体   繁体   中英

Appending values of a key before spaces

I am using ruamel.yaml to insert some values but it appends the value after a space instead of before the space. The current code appends the value after a line space as shown in the YAML file below. The YAML output which is marked ** NEW VALUE INSERTED HERE**

prefix_state:

  v4:    
    8.8.8.8/32:
      description: GOOGLE_DNS
      enabled: true
      tags:
        - dns
      community:
        lb:
          - SELF_NO_EXPORT
          - TELCOM_NO_EXPORT
          - BUSINESS_NO_EXPORT

          **- <NEW VALUE INSERTED HERE>**
    10.10.1.0/24:
      description: SELF_LOCAL
      enabled: True
      tags:
        - local
      community:
        lb:
          - <NEW VALUE INSERTED HERE>

The code used to append the values in the yaml file is as below:

yamldata=yaml.load(prefix_state_data,Loader=yaml.RoundTripLoader)
for arg in argv:
  if arg is None:
    pass
  else:
    for i in yamldata['prefix_state']['v4']:
      if yamldata['prefix_state']['v4'][i]['community']['lb'] is not None:
        yamldata['prefix_state']['v4'][i]['community']['lb'].append(arg+'_NO_EXPORT')
      else:
        yamldata['prefix_state']['v4'][i]['community']['lb']=[arg+'_NO_EXPORT']```

Expected end result is as below:

  v4:    
     8.8.8.8/32:
      description: GOOGLE_DNS
      enabled: true
      tags:
        - dns
      community:
        lb:
          - SELF_NO_EXPORT
          - TELECOM_NO_EXPORT
          - BUSINESS_NO_EXPORT
          **- <NEW VALUE INSERTED HERE>**

    10.10.1.0/24:
      description: SELF_LOCAL
      enabled: True
      tags:
        - local
      community:
        lb:
          - <NEW VALUE INSERTED HERE>

In ruamel.yaml, comments, and empty lines are associated with the element before them : if they follow a key-value pair they are associated with the preceding key, if they follow a sequence they are associated with the index of the element they follow.

You seem to mistakingly assume your "empty" line is "after" the sequence, or maybe even between the keys 8.8.8.8/32 and 10.10.1.0/24 . ruamel.yaml has no such concepts and none of the documentation or answers here on StackOverflow make that kind of a claim AFAIK (and if they do please point out where you got to this misinformation).


Assuming you have a sequence with a comment consisting of one or more lines (and empty lines are considered comments without a starting #), after a specific index (which maybe the index of the last item, as in your case), you can do one of two things:

  • insert a new item after the existing item that has the comment, and move the comment (inserting after the last item is the same as appending)

  • insert the old item before its original position and overwrite the original old item, which is now one index further, with the new item. The comment/empty line will now be associated with the

Since the second option is more easy to accomplish, I'll use that here

import sys
import ruamel.yaml

arg = 'XXX'

yaml_str = """\
prefix_state:
  v4:    
    8.8.8.8/32:
      description: GOOGLE_DNS
      enabled: true
      tags:
        - dns
      community:
        lb:
          - SELF_NO_EXPORT
          - TELCOM_NO_EXPORT
          - BUSINESS_NO_EXPORT

    10.10.1.0/24:
      description: SELF_LOCAL
      enabled: True
      tags:
        - local
      community:
        lb:
"""

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=2, sequence=4, offset=2)
data = yaml.load(yaml_str)
yd = data['prefix_state']['v4']
for i in yd:
    if yd[i]['community']['lb'] is not None:
        lb = yd[i]['community']['lb']
        lb.insert(len(lb)-2, lb[len(lb)-1])
        lb[-1] = arg + '_NO_EXPORT'
    else:
        yd[i]['community']['lb'] = [arg + '_NO_EXPORT']
yaml.dump(data, sys.stdout)

which gives:

prefix_state:
  v4:
    8.8.8.8/32:
      description: GOOGLE_DNS
      enabled: true
      tags:
        - dns
      community:
        lb:
          - SELF_NO_EXPORT
          - BUSINESS_NO_EXPORT
          - TELCOM_NO_EXPORT
          - XXX_NO_EXPORT

    10.10.1.0/24:
      description: SELF_LOCAL
      enabled: true
      tags:
        - local
      community:
        lb:
          - XXX_NO_EXPORT

Please note that the file format is YAML, the package name ruamel.yaml , and that the recommended extension for YAML files has been .yaml since 2006. But most importantly YML is something about as old as YAML, but an entirely different format.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM