用Bash替换yml中的line值

时间:2018-02-14 09:35:35

标签: bash awk sed

我有以下格式的yml文件。

Backendapp:
  Name: spring-rest 
  Image: "testuser/backend"
  ImageTag: "latest"
  ImagePullPolicy: "Always"
  Port: 8080
  replicaCount: 2

Frontendapp:
  Name: spring-js
  Image: "testuser/frontend"
  ImageTag: "latest"
  ImagePullPolicy: "Always"
  replicaCount: 2

如何通过Bash替换Backendapp的'Image','ImageTag'?

编辑:说文件名是test.yml,上面有内容。然后,我想将'Image'和'ImageTag'替换为'Backendapp'部分的另一个值(比如'teststring','latest2'resp。)。

修改后的文件应如下所示。

Backendapp:
  Name: spring-rest 
  Image: "teststring"
  ImageTag: "latest2"
  ImagePullPolicy: "Always"
  Port: 8080
  replicaCount: 2

Frontendapp:
  Name: spring-js
  Image: "testuser/frontend"
  ImageTag: "latest"
  ImagePullPolicy: "Always"
  replicaCount: 2

3 个答案:

答案 0 :(得分:2)

关注awk可能对您有所帮助:

awk '
/:$/{
  flag=""
}
/Backendapp/||/Frontendapp/{
  flag=1
}
flag && NF && (/Image:/||/ImageTag:/){
  match($0,/^[[:space:]]+/);
  val=substr($0,RSTART,RLENGTH);
  $NF="teststring";
  print val $0;
  next
}
1
'   Input_file

输出如下:

Backendapp:
  Name: spring-rest
  Image: teststring
  ImageTag: teststring
  ImagePullPolicy: "Always"
  Port: 8080
  replicaCount: 2

Frontendapp:
  Name: spring-js
  Image: teststring
  ImageTag: teststring
  ImagePullPolicy: "Always"
  replicaCount: 2

解决方案第二: 根据OP,OP需要将shell变量放入awk变量中,然后以下内容可能有所帮助:

awk -v val_shell="$shell_variable" '
/:$/{
  flag=""
}
/Backendapp/||/Frontendapp/{
  flag=1
}
flag && NF && (/Image:/||/ImageTag:/){
  match($0,/^[[:space:]]+/);
  val=substr($0,RSTART,RLENGTH);
  $NF=val_shell;
  print val $0;
  next
}
1
'   Input_file

答案 1 :(得分:1)

Awk 解决方案:

awk 'NF==1 && /^[^[:space:]]+:/{ f=(/^(Back|Front)endapp:/) }
     f && $1 ~ /^Image(Tag)?:/{ $1="  teststring" }1' test.yml

输出:

Backendapp:
  Name: spring-rest
  teststring: "testuser/backend"
  teststring: "latest"
  ImagePullPolicy: "Always"
  Port: 8080
  replicaCount: 2

Frontendapp:
  Name: spring-js
  teststring: "testuser/frontend"
  teststring: "latest"
  ImagePullPolicy: "Always"
  replicaCount: 2

答案 2 :(得分:1)

这是您的解决方案。它主要使用SED进行更换。只需将“START OF SCRIPT”和“END OF SCRIPT”之间的位复制并粘贴到任何bash脚本中然后运行(下面的简单说明):

脚本开始...

#!/bin/bash

# SED script will be stored here ...

sedscript=/tmp/sedscript.sed

# first argument to script is the parent name ...

parent="${1}"

# second argument to the script is child name...

child="${2}"

# third argument is the value to replace the CHILD value with ...

value="$3"

cat << EOF > "${sedscript}"

# find parent ...
/^${parent}:.*$/{

    p

    # load next line into input ...
    n

    # another parent found to print it ...
    /^[a-z|A-Z|0-9]\{1\}:.*$/{

        # we have found another parent
        # so stop processing ...

        b print_default_text
    }

    :search_for_child

    /^[ |   ]*$child[ | ]*:.*$/{

        s/^\([^:]*:[ |\"|   ]*\)[^\"]*\(.*\)$/\1$value\2/p

        b dont_print_default_text
    }

    p
    n
    b search_for_child
}


:print_default_text
p

:dont_print_default_text

EOF

sed -n -f "${sedscript}" "input.yml"

...脚本结束

现在我们将脚本保存为alter.sh(例如),然后像这样运行它(将Frontendapp / Image更改为“another-image-name”):

./ alter.sh Frontendapp图片“another-image-name”

INPUT FILE ....

Backendapp:   名称:弹簧休息   图片:“teststring”   ImageTag:“latest2”   ImagePullPolicy:“总是”   港口:8080   replicaCount:2

Frontendapp:   姓名:spring-js   图片:“testuser / frontend”   ImageTag:“最新”   ImagePullPolicy:“总是”   replicaCount:2

输出文件....

Backendapp:   名称:弹簧休息   图片:“teststring”   ImageTag:“latest2”   ImagePullPolicy:“总是”   港口:8080   replicaCount:2

Frontendapp:   姓名:spring-js   图片:“another-image-name”   ImageTag:“最新”   ImagePullPolicy:“总是”   replicaCount:2

注意:脚本也会处理引号,即如果原始值有引号,那么新值也会用引号括起来。

希望这会有所帮助......