我有一个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