如果删除最后一个元素,则自动删除空白行

时间:2019-07-15 08:24:32

标签: python ruamel.yaml

我正在使用ruamel.yaml删除一些值,除非删除的值是最后一个值,否则它工作正常,否则最终也会删除空白行。

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:
          - SELF_NO_EXPORT
          - TELCOM_NO_EXPORT
          - BUSINESS_NO_EXPORT

我阅读了有关插入要添加的注释的信息,但实际上不确定如何在此处添加注释。

用于删除yaml文件中值的代码如下:

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:
        pass
      else:
        for j in yamldata ['prefix_state']['v4'][i]['community']['lb']:
          if argv[0] + '_NO_EXPORT' == j:
            lb= yamldata ['prefix_state']['v4'][i]['community']['lb']
            lb.remove(j)

预期的最终结果如下:

prefix_state:

  v4:    
    8.8.8.8/32:
      description: GOOGLE_DNS
      enabled: true
      tags:
        - dns
      community:
        lb:
          - SELF_NO_EXPORT
          - TELCOM_NO_EXPORT
<<<BLANK LINE>>>
    10.10.1.0/24:
      description: SELF_LOCAL
      enabled: True
      tags:
        - local
      community:
        lb:
          - SELF_NO_EXPORT
          - TELCOM_NO_EXPORT
<<<BLANK LINE>>>

由于代码而输出:

prefix_state:

  v4:    
    8.8.8.8/32:
      description: GOOGLE_DNS
      enabled: true
      tags:
        - dns
      community:
        lb:
          - SELF_NO_EXPORT
          - TELCOM_NO_EXPORT
    10.10.1.0/24:
      description: SELF_LOCAL
      enabled: True
      tags:
        - local
      community:
        lb:
          - SELF_NO_EXPORT
          - TELCOM_NO_EXPORT

1 个答案:

答案 0 :(得分:0)

如果您将数据加载到data,然后在页面上打印出注释属性(.ca), 顺序使用:

print(data['prefix_state']['v4']['8.8.8.8/32']['community']['lb'])

您将看到的是:

Comment(comment=None,
  items={2: [CommentToken('\n\n', line: 12, col: 12), None, None, None]})

您会看到注释附加在第二项的序列上, 出现注释前的最后一个节点(空 行作为注释处理)。因此,如果您删除创建的项目 对于该节点,您的期望应该是关联的注释 该项目也将被删除。

您的代码不完整,目前尚不清楚yamldataargv的来源,但是 您可以在文件input。yaml`中使用您的YAML

import sys
import ruamel.yaml


yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
with open('input.yaml') as prefix_state_data:
     data = yaml.load(prefix_state_data)

lb = data['prefix_state']['v4']['8.8.8.8/32']['community']['lb']

for idx, j in enumerate(lb):
    idx_to_remove = []
    if 'BUSINESS_NO_EXPORT' == j:
        if idx > 0 and lb.ca.items.get(idx) is not None and lb.ca.items.get(idx-1) is None:
            lb.ca.items[idx-1] = lb.ca.items.pop(idx)
            idx_to_remove.append(idx)
    for idx in reversed(idx_to_remove):
        lb.pop(idx)

yaml.dump(data, sys.stdout)

给出:

prefix_state:

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

    10.10.1.0/24:
      description: SELF_LOCAL
      enabled: true
      tags:
      - local
      community:
        lb:
        - SELF_NO_EXPORT
        - TELCOM_NO_EXPORT
        - BUSINESS_NO_EXPORT

注意事项:

  • 永远不要使用for更改要遍历的列表 环。如果这是最后一个元素和循环,那可能会起作用 终止,但如果没有终止,您将得到错误的结果:

    a = [1, 2, 3]
    for x in a:
        print(x, a)
        a.remove(x)
    

    给予:

    1 [1, 2, 3]
    3 [2, 3]
    

    我希望很清楚,为什么您需要从最新的索引中找到任何索引。

  • 我将要删除的元素的注释复制到前一个元素(如果存在) 并且还没有评论。

  • 或者,您也可以将注释从最后一个序列项移至 上级集合的最后一个键值对,例如:

community.ca.items ['lb'] = commnity ['lb'] ca.items.pop(2)#确保您计算出2的值

您还可以使用以下方法在列表的最后一个元素中添加注释:

lb = data['prefix_state']['v4']['8.8.8.8/32']['community']['lb']

lb.remove('BUSINESS_NO_EXPORT')
lb.yaml_add_eol_comment('\n\n', len(lb)-1)
yaml.dump(data, sys.stdout)

但是它将在评论之前插入#,因为它不是以一个和 解决这个问题并不完全是简单的。