我正在使用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
答案 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]})
您会看到注释附加在第二项的序列上, 出现注释前的最后一个节点(空 行作为注释处理)。因此,如果您删除创建的项目 对于该节点,您的期望应该是关联的注释 该项目也将被删除。
您的代码不完整,目前尚不清楚yamldata
和argv
的来源,但是
您可以在文件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]
我希望很清楚,为什么您需要从最新的索引中找到任何索引。
我将要删除的元素的注释复制到前一个元素(如果存在) 并且还没有评论。
或者,您也可以将注释从最后一个序列项移至 上级集合的最后一个键值对,例如:
您还可以使用以下方法在列表的最后一个元素中添加注释:
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)
但是它将在评论之前插入#
,因为它不是以一个和
解决这个问题并不完全是简单的。