更新锚点中定义的对象字段

Update an object field defined in an anchor

我有一个如下所示的 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

我发现类似的唯一方法是使用我发现的这个表达式 in the yq (v4) documentation:

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 实现中的一个错误。

解决方案是使用合并来断开到别名的持久链接:

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