如何合并两个 yaml 文件,同时使用 yq4 覆盖重复项

问题描述 投票:0回答:1

我有两个文件。第一个文件是设置所有默认值的文件。 defauly_deploy.yaml

deploy:
  - env: prod
    disabled: true
    namespaces: 
      - production
    disable_switch:
      a: b
      c: d
      e: f
  - env: dev
    disabled: true
    namespaces: 
      - development
    disable_switch:
      a: b
      c: d
      e: f

我还有另一个文件,它是特定于项目的。因为我已经设置了所有默认值,所以我想只使用开发环境。然后,我仅将以下内容添加到文件“dev”之一。 部署.yaml

deploy:
  - env: dev
    disabled: false
    namespaces: 
      - development
    disable_switch:
      a: b

如果我将文件deploy.yaml加载到default_deploy.yaml中,我会得到以下信息:

$ yq eval '. *d load("deploy.yaml")' default_deploy.yaml
deploy:
  - env: dev
    disabled: false
    namespaces:
      - myns
    disable_switch:
      a: y
      c: d
      e: f
  - env: dev
    disabled: true
    namespaces:
      - development
    disable_switch:
      a: b
      c: d
      e: f

我想真正得到:

deploy:
  - env: prod
    disabled: true
    namespaces:
      - production
    disable_switch:
      a: b
      c: d
      e: f
  - env: dev
    disabled: false
    namespaces:
      - myns
    disable_switch:
      a: y
      c: d
      e: f

我想知道问题是否实际上是列表的使用。 如果我将格式更改为 dict,它就像一个魅力,这是新的输出:

deploy:
  prod:
    disabled: true
    namespaces:
      - production
    disable_switch:
      a: b
      c: d
      e: f
  dev:
    disabled: false
    namespaces:
      - myns
    disable_switch:
      a: y
      c: d
      e: f

有什么线索吗?谢谢!!

yq
1个回答
0
投票

我想知道问题是否实际上是列表的使用。如果我将格式更改为 dict,它就像一个魅力

是的,因为合并数组时,

yq
可以将它们相互追加(使用
*+
),或者按索引合并它们(这就是您在第一项中看到冲突的原因)。
yq
本身无法确定
.env
子项是要匹配的子项;这必须以编程方式发生(请参阅有关如何将对象数组合并在一起,匹配键的手册)。

您还发现的一个选项是将两个数组都转换为映射,执行合并,然后再次重新构造数组(如果需要)。

另一种方法是迭代项目,并对匹配的项目执行“本地”合并。这是一种使用

ireduce
进行迭代,并使用
select
来过滤匹配项的方法:

yq '.deploy[] as $i ireduce (
  load("default_deploy.yaml"); (.deploy[] | select(.env == $i.env)) *=d $i
)' deploy.yaml

另一种方法是首先执行附加数组的合并(或者如果除了要合并的

.deploy
键之外没有其他内容,则简单地添加两个数组),然后按引用键进行分组,并对组执行内部合并发现:

yq '. *+ load("deploy.yaml") | .deploy |= [group_by(.env)[] | .[0] *d .[1]]' \
  default_deploy.yaml

yq ea '[.deploy[]] | [group_by(.env)[] | .[0] *d .[1]] | {"deploy": .}' \
  default_deploy.yaml deploy.yaml
© www.soinside.com 2019 - 2024. All rights reserved.