更新在定位中定义的对象字段



我有一个yaml文件,它看起来像这样:

item_value: &item_value
value: true
array:
- name: item_1
<<: *item_value
- name: item_2
<<: *item_value

我想更新第一个项目的值,以便有这样的东西:

array:
- name: item_1
value: false
- name: item_2
value: true

我发现有类似内容的唯一方法是使用我在yq(v4(文档中找到的表达式:

yq e '( explode(.) | .array.[] | select(.name == "item_1") | .value = false ) as $test | explode(.) | .array.[] |= (. as $cur | $cur * ($test | select(.name == $cur.name)))' test.yaml

这似乎真的很棘手,我注意到使用以下较短的表达式,我得到了相同的(坏的(结果(顺便说一句,我不明白为什么这个有效(:

yq e '( explode(.) | .array.[] | select(.name == "item_1") | .value = false ) as $test' test.yaml

结果:

item_value:
value: false
array:
- name: item_1
value: false
- name: item_2
value: false

使用yq(Python版本,而不是您正在使用的Go版本(我能解决你的任务。

#!/bin/bash
FILE='
item_value: &item_value
value: true
array:
- name: item_1
<<: *item_value
- name: item_2
<<: *item_value
'
yq -y --arg name "item_1" '(.array[] | select(.name == $name) | .value) |= false' <<< "$FILE"

输出

item_value:
value: true
array:
- value: false
name: item_1
- value: true
name: item_2

使用yq(您正在使用的Go版本(,我也会得到具有相同表达式的错误输出。

yq e '(.array[] | select(.name == "item_1") | .value) |= false' test.yaml

输出

item_value: &item_value
value: false
array:
- name: item_1
!!merge <<: *item_value
- name: item_2
!!merge <<: *item_value

使用作为输入

array:
- name: item_1
value: true
- name: item_2
value: true

一切正常:

yq e '(.array[] | select(.name == "item_1") | .value) |= false' test.yaml

array:
- name: item_1
value: false
- name: item_2
value: true

因此,它是yq实现中的一个缺陷。

解决方案是使用merge来中断到别名的持久链接:

yq e '(.array[] | select(.name=="item_1")) |= explode(.) * {"value": false}' test.yaml

最新更新