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

Auto remove blank line in case last element is removed

我正在使用 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

如果加载数据到data然后打印出comment属性(.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)

但这会在评论前插入一个 #,因为它不是以 one and 解决这个问题并非易事。