简体   繁体   English

使用 sed 将 yaml 文件中的值替换为多行字符串

[英]Replace a value in yaml file with multi line string using sed

I have been trying to replace/add value of a field in yaml with an env variable that has multi line string, using below syntax我一直在尝试使用具有多行字符串的 env 变量替换/添加 yaml 中的字段值,使用以下语法

replacewith=" |-
  multi
  line
  string"
sed -i -e "s/^\(\s*key-in-yaml\s*:\s*\).*/\1 $replacewith/"  somefile.yaml

We can assume that key-in-yaml doesn't have any value by default.我们可以假设key-in-yaml默认没有任何值。 Above comand results in上面的命令导致

sed: -e expression #1, char 37: unterminated `s' command

I also want the indentation to be maintained.我也希望保持缩进。

If this is the content of yaml file如果这是 yaml 文件的内容

apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
  annotations:
    alm-examples:
    capabilities: Basic Install

after that sed command i was expecting在那之后sed命令我期待

apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
  annotations:
    alm-examples: |-
      multi
      line
      string
    capabilities: Basic Install

With your shown samples, please try following, in case you are ok with awk .对于您显示的示例,请尝试以下操作,以防您对awk

awk -v str="$replacewith" '
1;
/annotations:/{ found=1 }
found && /alm-examples: \|-/{
  print str
  found=""
}
' Input_file

Once you are happy with above results(which will be shown on terminal) and in case you want to save them into Input_file itself then append > temp && mv temp Input_file to above command.一旦您对上述结果感到满意(将显示在终端上)并且如果您想将它们保存到 Input_file 本身然后 append > temp && mv temp Input_file到上面的命令。

sed -E '/alm-examples/s/(.*)$/printf "\1 $replacewith"/e' somefile.yaml

This uses s///e to shell out to printf which will handle the multiline string better than attempts to inline it with sed commands.这使用s///e到 shell 到printf ,这将比尝试使用 sed 命令内联它更好地处理多行字符串。 It is printf expanding the string, not sed , because the sed command is in single quotes.它是printf扩展字符串,而不是sed ,因为 sed 命令在单引号中。

This also works, with & replacing the \1 , because the line break doesn't get passed to printf either way:这也适用于&替换\1 ,因为换行符不会以任何方式传递给 printf :

sed -E '/alm-examples/s/.*/printf "& $replacewith"/e' somefile.yaml

Or, to depend on annotations: in the prior line:或者,依赖annotations:在前一行:

sed -E '/annotations:/{N;/alm-examples/s/.*/printf "& $replacewith"/e}' somefile.yaml

I have decided to use yq and it has been working great even for complex fields in yaml for example abc[0].d=env-var-multiline .我决定使用yq ,即使对于 yaml 中的复杂字段,例如abc[0].d=env-var-multiline ,它也能很好地工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM