linux 如何使用bash脚本修改yaml文件的嵌套模块

olhwl3o2  于 2023-05-06  发布在  Linux
关注(0)|答案(5)|浏览(188)

我试图改变一个特定的字在yaml文件使用sed命令

kind: Pod
metadata:
  name: abc12
spec:
  containers:
  - image: ubuntu:latest
    name: Ubuntu
    imagePullPolicy: IfNotPresent
  - image: ngnix: latest
    name: Nginx
    imagePullPolicy: IfNotPresent
...

已尝试使用以下命令sed '/^ * image: ngnix:latest/,/^*[^:]*:s/imagePullPolicy: IfNotPresent/imagePullPolicy: {}/' file.yaml
我需要使用sed/awk命令仅为ngnix更改imagePullPolicy内容。
以下是我想要的输出:

kind: Pod
metadata:
  name: abc12
spec:
  containers:
  - image: ubuntu:latest
    name: Ubuntu
    imagePullPolicy: IfNotPresent
  - image: ngnix: latest
    name: Nginx
    imagePullPolicy: {}
...

谢谢

66bbxpm5

66bbxpm51#

one case(GNU sed)

sed -E '
/^\s*-\s*image:\s*ngnix/{
  :top
  N
  /imagePullPolicy/!btop
  s/(imagePullPolicy:).*/\1 \{\}/
}' file.yaml

然而,这可能不是通用的。

lb3vh1jj

lb3vh1jj2#

使用任何POSIX awk:

$ cat tst.sh
#!/usr/bin/env bash

awk '
    match($0,/^[[:space:]-]*/) {
        if      ( RLENGTH > prevRlength ) { indent++ }
        else if ( RLENGTH < prevRlength ) { indent-- }
        prevRlength = RLENGTH

        key = val = substr($0,RLENGTH+1)
        sub(/[[:space:]]*:.*/,"",key)
        sub(/[^:]*:[[:space:]]*/,"",val)

        indent2key[indent] = key
    }

    (indent == 2) && (indent2key[0] == "spec") && (indent2key[1] == "containers") {
        if ( $1 == "-" ) {
            gotImage = 0
        }

        if ( (key == "image") && (val ~ /^ngnix:/) ) {
            gotImage = 1
        }

        if ( gotImage && (key == "imagePullPolicy") && (val == "IfNotPresent") ) {
            sub(/:.*/,": {}")
        }
    }

    { print }
' "${@:--}"
$ ./tst.sh file
kind: Pod
metadata:
  name: abc12
spec:
  containers:
  - image: ubuntu:latest
    name: Ubuntu
    imagePullPolicy: IfNotPresent
  - image: ngnix: latest
    name: Nginx
    imagePullPolicy: {}

上面假设image:总是在imagePullPolicy:之前,就像你发布的例子一样。

fhg3lkii

fhg3lkii3#

使用GNU sed

$ sed -E ':a;/- image: ngnix: latest/,/- image:/{n;s/(imagePullPolicy: ).*/\1{}/;ba}' input_file
kind: Pod
metadata:
  name: abc12
spec:
  containers:
  - image: ubuntu:latest
    name: Ubuntu
    imagePullPolicy: IfNotPresent
  - image: ngnix: latest
    name: Nginx
    imagePullPolicy: {}
...
9rygscc1

9rygscc14#

首先,修复YAML第9行:image: ngnix: latest =〉image: nginx:latest(2个错误)。

固定输入:
kind: Pod
metadata:
  name: abc12
spec:
  containers:
    - image: ubuntu:latest
      name: Ubuntu
      imagePullPolicy: IfNotPresent
    - image: nginx:latest
      name: Nginx
      imagePullPolicy: IfNotPresent
使用正确的YAML解析器,yq
yq -y '
  (
    .spec.containers[] | 
     select(.image=="nginx:latest" and .imagePullPolicy=="IfNotPresent")
    .imagePullPolicy
   ) = {}
' file

来自jq@libera.irc的emanuele6

Online Demo
输出
kind: Pod
metadata:
  name: abc12
spec:
  containers:
    - image: ubuntu:latest
      name: Ubuntu
      imagePullPolicy: IfNotPresent
    - image: nginx:latest
      name: Nginx
      imagePullPolicy: {}

编辑inplace,可以使用-yi

ttcibm8c

ttcibm8c5#

非常简单的sed,假设唯一的IfNotPresent字符串是你想要替换的image: ngniximagePullPolicy的行:

sed '/image: ngnix:/,/imagePullPolicy/ s/IfNotPresent/{}/' file.yaml

换句话说,找到特定的行范围,然后在该/START/,/END/范围内进行最简单的替换

相关问题