我有两个文件。第一个文件是设置所有默认值的文件。 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
有什么线索吗?谢谢!!
我想知道问题是否实际上是列表的使用。如果我将格式更改为 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