skip to Main Content

I am trying to change one specific word in yaml file using sed command

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

Tried using the following command
sed '/^ * image: ngnix:latest/,/^*[^:]*:s/imagePullPolicy: IfNotPresent/imagePullPolicy: {}/' file.yaml

I am required to change the imagePullPolicy content only for ngnix using sed/awk command.

Following is my desired output:

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

Thanks

4

Answers


  1. one case (GNU sed)

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

    However, this may not be generic.

    Login or Signup to reply.
  2. Using any 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: {}
    

    The above assumes that image: always comes before imagePullPolicy: as in the example you posted.

    Login or Signup to reply.
  3. Using 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: {}
    ...
    
    Login or Signup to reply.
  4. Fisrt, fix your YAML line 9: image: ngnix: latest => image: nginx:latest (2 errors).

    Then, use a proper parser, yq:

    yq '(.spec.containers[] | select(.image=="nginx:latest").imagePullPolicy) = {}' file
    

    Online Demo

    Credits to emanuele6 from [email protected]

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

    You need a little bit more work to include all needed objects.

    To edit inplace, you can use -yi.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search