【问题标题】:Passing Variable value after specific string in YAML file在 YAML 文件中的特定字符串之后传递变量值
【发布时间】:2017-10-09 11:33:36
【问题描述】:

我有一个 Yaml 格式的文件(如下所述)。

values.yml

replicaCount: 2
strategy: 
  type: RollingUpdate
  rollingUpdate:
     maxSurge: 1
     maxUnavailable: 1
minReadySeconds: 5
nodeSelector:
       role: nginxplus
image:
  repository: 2xxxxxxxxxxx6.dkr.ecr.us-east-1.amazonaws.com/miqp-devops
  tag: foo
  pullPolicy: IfNotPresent

现在我想用另一个值替换键标记。该值来自一个变量。

例如,

 VAR=bar
 echo $VAR
 bar

我想要一些可以编辑我的 values.yml 文件并替换的东西

标签:foo 到标签:bar

谢谢

【问题讨论】:

  • 到目前为止你有什么尝试?一个简单的sed 应该很容易在你的情况下工作
  • 适合这项工作的工具确实类似于jq。 (是的,它生成有效的 YAML——所有 JSON 都是有效的 YAML)。否则,您将受到所有关于使用结构未知工具编辑结构化数据的常见警告。
  • (也就是说,如果您的输入格式不正确或数据的表示形式发生了一点变化,那些不知道结构的工具将不知道如何处理它;您的sed仅当输入精确地保持其当前格式时,基于 -based 的答案才适用于输入,但相同数据的其他文本版本是同样有效的数据,它们无法正确识别)。跨度>
  • 处理 HTML/XML/JSON/YAML/... 数据的经验法则——使用正确的解析器。

标签: linux bash awk sed yaml


【解决方案1】:

sed方法:

var="bar"
sed -i "s/^\([[:space:]]*tag:[[:space:]]*\).*/\1$var/" values.yml

最后的values.yml内容:

replicaCount: 2
strategy: 
  type: RollingUpdate
  rollingUpdate:
     maxSurge: 1
     maxUnavailable: 1
minReadySeconds: 5
nodeSelector:
       role: nginxplus
image:
  repository: 2xxxxxxxxxxx6.dkr.ecr.us-east-1.amazonaws.com/miqp-devops
  tag: bar
  pullPolicy: IfNotPresent

【讨论】:

  • 请注意,如果文件包含image: {"tag": "foo", "repository": "...", "pullPolicy": "IfNotPresent" },则输入仍然有效——并且语义相同——YAML。在 YAML 规范中有很多不同的方式来编写这些内容,而这种 sed 方法只处理一个。
【解决方案2】:

要稳健地执行此操作(是的,它会更改数据的表示形式,但它仍然是 100% 有效的 YAML):

# This uses/requires the PyYAML library; "pip install PyYAML"
yaml2json() {
  python -c 'import yaml, json, sys; print json.dumps(yaml.safe_load(sys.stdin))'
}

editYaml() {
  local file=$1; shift
  local tempfile=$(mktemp "${file}.XXXXXX")
  local retval

  if jq "$@" < <(yaml2json <"$file") >"$tempfile"; then
    chmod --reference="$file" -- "$tempfile" # on GNU systems, preserve permissions
    mv -- "$tempfile" "$file"
  else
    retval=$?
    rm -f -- "$tempfile"
    return "$retval"
  fi
}

newTag=bar
editYaml values.yml --arg newTag "$newTag" '.image.tag = $newTag'

这种方法可确保将相同的数据转换为相同的输出,无论它是如何表示的——这很重要,因为 YAML 提供了多种文本不同的方式来编写相同的语义内容。

【讨论】:

    【解决方案3】:

    我会为此使用 perl,并带有 YAML::Tiny 模块

    cp values.yml values.yml.orig
    perl -MYAML::Tiny -se '
        $file = shift @ARGV; 
        $yaml = YAML::Tiny->read($file); 
        $yaml->[0]{image}{tag} = $newtag; 
        $yaml->write($file);
    ' -- -newtag="bar" values.yml 
    cat values.yml
    
    ---
    image:
      pullPolicy: IfNotPresent
      repository: 2xxxxxxxxxxx6.dkr.ecr.us-east-1.amazonaws.com/miqp-devops
      tag: bar
    minReadySeconds: '5'
    nodeSelector:
      role: nginxplus
    replicaCount: '2'
    strategy:
      rollingUpdate:
        maxSurge: '1'
        maxUnavailable: '1'
      type: RollingUpdate
    

    【讨论】:

      猜你喜欢
      • 2011-07-31
      • 1970-01-01
      • 2020-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多