首页 > 解决方案 > 如何去除 YAML 格式配置文件中的重复行?

问题描述

我有一堆清单/yaml 文件,这些文件可能有也可能没有这些键值对重复项:

...
app: activity-worker
app: activity-worker
...

我需要搜索每个文件并找到那些重复项,以便删除其中一个。

注意:我知道要替换目录(例如,)的所有文件中的某个字符串(例如,切换service:到),我可以运行. 我正在寻找线条之间的关系。app:devgrep -l 'service:' dev/* | xargs sed -i "" 's/\service:/app:/g'

标签: unixduplicatesyaml

解决方案


你所说的 YAML,不是 YAML。YAML 规范 非常明确地声明映射中的键必须是唯一的,并且您的键不是:

映射节点的内容是一组无序的键:值节点对,每个键都是唯一的。YAML 对节点没有进一步的限制。特别是,键可以是任意节点,同一个节点可以用作多个键的值:值对,映射甚至可以将自身包含为键或值(直接或间接)。

另一方面,一些库错误地实现了这一点,选择用后面的值覆盖与键关联的任何先前值。在您的情况下,由于值相同,因此采用哪个值并不重要。

此外,您的块样式表示不是在“YAML”中表示映射的键值对的唯一方法,这些重复项也可以在映射中表示,如

{...., app: activity-worker, app: activity-worker, .... }

这两个事件不一定相邻,也不一定在同一行。以下内容在语义上也与您的输入等效“YAML”:

{...., app: activity-worker, app: 
       activity-worker, .... }

ruamel.yaml如果您有此类错误的“YAML”文件,清理它们的最佳方法是使用(免责声明:我是该软件包的作者)的往返功能 ,以及它在包含重复的错误输入时切换除/警告的能力键。您可以使用以下命令为您的 Python(虚拟环境)安装它:

pip install ruamel.yaml

假设您的文件被调用input.yaml并且它包含:

a: 1   # some duplicate keys follow
app: activity-worker
app: activity-worker
b: "abc"

您可以运行以下单行:

python -c "import sys; from ruamel.yaml import YAML; yaml = YAML(); yaml.preserve_quotes=yaml.allow_duplicate_keys=True; yaml.dump(yaml.load(open('input.yaml')), sys.stdout)"

要得到:

a: 1   # some duplicate keys follow
app: activity-worker
b: "abc"

如果您的输入是这样的:

{a: 1, app: activity-worker, app: 
    activity-worker, b: "abc"}

输出将是:

{a: 1, app: activity-worker, b: "abc"}

推荐阅读