用yq替换Yaml值,用新值作为bash函数的输出,该函数接受当前值作为输入 概述 差不多 但是使用yq yq属于基斯利乌克的yq非其他yq项目(pip安装yq) 细节

用yq替换Yaml值,用新值作为bash函数的输出,该函数接受当前值作为输入 概述 差不多 但是使用yq yq属于基斯利乌克的yq非其他yq项目(pip安装yq) 细节,yaml,substitution,yq,Yaml,Substitution,Yq,我有一个bash函数: function replace\u image\u repo(){ echo“nexus.local/${1}” } 另一方面,我有一个YAML文件: #pod.yaml 种类:豆荚 # ... 规格: 容器: -名称:网站 图片:nginx -名称:记录器 图片:abdennour/logger 我可以用静态值替换.image键出现的所有值: yq-y'(..|.image?)|=“mynewimage”pod.yaml 结果如预期: #pod.yaml 种类:

我有一个bash函数:

function replace\u image\u repo(){
echo“nexus.local/${1}”
}
另一方面,我有一个YAML文件:

#pod.yaml
种类:豆荚
# ...
规格:
容器:
-名称:网站
图片:nginx
-名称:记录器
图片:abdennour/logger
我可以用静态值替换
.image
键出现的所有值:

yq-y'(..|.image?)|=“mynewimage”pod.yaml
结果如预期:

#pod.yaml
种类:豆荚
# ...
规格:
容器:
-名称:网站

图片:mynewimage#你可以做得更好。由于使用了下面的
jq
功能,因此可以使用后者的
--arg
字段来传递要替换的值。例如,您的案例可以定制为传递要传递的旧字符串和新字符串

另外,
jq
过滤器表达式
(..|.image?)|=“mynewimage”
不是最好的方法,因为
使用了,您可能会在修改的结果中得到
null
值。正确的方法是修改过滤器以匹配包含字符串的确切对象,并替换为目标值

建议删除shell函数中的非标准关键字
function
,尤其是
bash

replace_image_repo() {
  printf '%s' "nexus.local/${1}"
}
并使用
yq
作为

yq -y --arg old "nginx" \
      --arg new "$(replace_image_repo "nginx")" \
      '.spec.containers |= map( select(.image == $old).image = $new )' yaml
或者,如果您的要求是将替换应用于容器下的所有
.image
字段,则可以在不使用shell函数的情况下执行以下操作

yq -y '.spec.containers |= map(.image = "nexus.local/\(.image)")' yaml 
通过将前缀字符串作为参数传递,可以对其进行进一步自定义

yq -y --arg prefix "nexus.local/" '.spec.containers |= map(.image = ($prefix + "\(.image)") )' yaml 

考虑到您关于必须使用非常复杂的shell函数的论点,您可以采用以下方法。这两个函数首先对YAML进行解析,以基于shell函数(complex,现在已抽象)获取新的图像名称,然后重新使用结果替换原始文件上的图像名称

这是因为
jq
还不允许在其表达式上下文中执行任意shell函数

#!/usr/bin/env bash

replace_image_repo() {
  printf '%s' "nexus.local/${1}"
}


convert_to_array() {
    local results=()
    while IFS= read -r image; do
        results+=( \"$(replace_image_repo "$image")\" )
    done < <(yq -r '.spec.containers[].image' yaml)
    local IFS=","
    printf '[%s]' "${results[*]}"
}


yq -y --argjson images "$(convert_to_array)" \
    'reduce range(0; $images | length) as $i (.;
       .spec.containers[$i].image = $images[$i])' yaml
#/usr/bin/env bash
替换_映像_repo(){
printf“%s”nexus.local/${1}
}
将_转换为_数组(){
本地结果=()
当IFS=读取-r图像时,执行以下操作
结果+=(\“$(替换\u image\u repo“$image”)\)

完成<谢谢@Inian。但是,bash函数
replace\u image\u repo
太复杂了,我没有时间将其转换为python。我这样放置函数定义只是为了了解关注点。@AbdennourTOUMI:请参阅更新,我已修改了答案,以确保对每个图像名称调用shell函数,并然后用更新后的名称将原始YAML更新回来