添加具有上一行缩进的新行

Add new line with previous line's indentation

我一直在努力通过使用 sed 在新行中添加元素来更新一些 yaml 文件。

sed命令(或另一个linux命令)必须匹配一个字符串(image:- image:),在新行上添加一个新元素,缩进与之前相同行。

问题是新行必须刚好在字符串 image: 之下,而不是在 - image:.

之下

示例:当 sed 匹配字符串 image 时,它会添加正确缩进的新行(就在 image 上方)

种类:DaemonSet
api版本:apps/v1
元数据:
  名称:印花布节点
规格:
  模板:
    规格:
      容器:
        - 名称:印花布节点
          <b>图片:</b>我的图片
          <b>imagePullSecret:</b>我的秘密
...

示例 2:当 sed 匹配字符串 - image 时,它会添加正确缩进的新行(就在 image 而不是 - 之上):

种类:DaemonSet
api版本:apps/v1
元数据:
  名称:印花布节点
规格:
  模板:
    规格:
      容器:
      <b>- 图片:</b> myimage
        <b>imagePullSecret:</b>我的秘密
...

不想要的是

种类:DaemonSet
api版本:apps/v1
元数据:
  名称:印花布节点
规格:
  模板:
    规格:
      容器:
      <b>- 图片:</b> myimage
      <b>imagePullSecret:</b>我的秘密

我已经尝试过 yq 命令来处理这个问题,但这是一个巨大的痛苦...

我在另一个线程中找到了这段代码,但在匹配 - image 字符串时它不起作用。

sed '/^ *image: .*/ { G; s/^\( *\)image: .*/&imagePullSecret: mysecret/; }' sed.yaml

我不容忍使用 sed 来解析 yaml,但如果你真的想这样做,你可以尝试这样的事情:

$ nl='                                                                                      
'
$ printf '   image:\n     - image:\n' | 
    sed -e "s/\(^\( *\)image:\)/\$nlinserted text/" \
    -e "s/\(^\( *\)- image:\)/\$nl  inserted text/"
   image:
   inserted text
     - image:
       inserted text

我建议:

sed '
    /^( *)image: .*/   {p; s//imagePullSecret: mysecret/; }
    /^( *)- image: .*/ {p; s//  imagePullSecret: mysecret/; }
' sed.yaml

s//replacement/ 中的空模式重用了最近使用的模式。

使用 GNU awk 来利用 gensub:

awk '/image: /{ str=[=10=] } str { print;str1=gensub(/(^.*)(image:.*$)/,"\1imagePullSecret: mysecret",str);sub("-"," ",str1);print str1;del str;next }1' file

解释:

awk '/image: /{ # Process the image tag
                 str=[=11=] # Set a variable str equal to the line
              } 
          str { # Process when we have a str set
                 print; # Print the current line
                 str1=gensub(/(^.*)(image:.*$)/,"\1imagePullSecret: mysecret",str); # Split the line into two sections and set str1 to the first section (get the leading spaces) and then the text we want to add.
                 sub("-"," ",str1); # Replace any - in the text with a space
                 print str1; # Print the new line
                 del str; # Remove the str variable
                 next # Skip to the next line
               }1' file

你可以使用这个 awk:

awk '/^[[:space:]-]*image/{ split([=10=],arr,/image.*/) 
                           gsub(/-/," ", arr[1])
                           rep=arr[1]
                           print [=10=]}
                       rep{ printf "%s%s\n", rep, "imagePullSecret: mysecret"
                       rep=""
                       next} 1' file

Yq v4 尚不支持添加地图,但您可以转换为 JSON,使用 jq,然后再转换回 YAML:

yq --tojson eval infile.yaml \
    | jq '.spec.template.spec.containers[0] += {imagePullSecret: "mysecret"}' \
    | yq eval -prettyPrint

这可能适合您 (GNU sed):

sed -E '/(-( ))?image:.*/{p;s//imagePullSecret: mySecret/}' file

image:.* 上匹配,并在前面加上可选的 -

打印当前行。

imagePullSecret: mySecret 替换为可选的 space,然后在 - 前面加了两次。