Search code examples
awkyamlindentation

awk to insert after nth occurrence with indentation


I am trying to edit a yaml file where indentation is critical. Below is the input

spec:
  replicas: 1
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app.kubernetes.io/name: myapp
      app.kubernetes.io/instance: myapp
  template:
    metadata:
      annotations:
        checksum/config: 2cee4a874d2afd91d92301f15efece5afbca3abc63ba3b2b
        checksum/tls-secrets: 649c0580ebbcf3ae194d17b8ac4cc2f1cda33f145da9764
      labels:
        app.kubernetes.io/name: myapp
        app.kubernetes.io/instance: myapp
    spec:
      serviceAccountName: myapp-acc
      containers:
        - name: myapp-pod
          image: "imagerepo"
          resources:
            requests:
              cpu: 500m
              memory: 800Mi

And i want to insert after "resources:" which is 11th occurrence in the yaml file and "serviceAccountName:" which is the 1st occurrence in the file with respective data with indentation. By that i mean whatever indentation search pattern has we can adjust the indentation of inserting text accordingly After resources: i want

    limits:
      cpu: 500m
      memory: 800Mi

After serviceAccountName

  imagePullSecrets:
    - name: imagepullsecret

Output file

spec:
  replicas: 1
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app.kubernetes.io/name: myapp
      app.kubernetes.io/instance: myapp
  template:
    metadata:
      annotations:
        checksum/config: 2cee4a874d2afd91d92301f15efece5afbca3abc63ba3b2b
        checksum/tls-secrets: 649c0580ebbcf3ae194d17b8ac4cc2f1cda33f145da9764
      labels:
        app.kubernetes.io/name: myapp
        app.kubernetes.io/instance: myapp
    spec:
      serviceAccountName: myapp-acc
      imagePullSecrets:
        - name: imagepullsecret
      containers:
        - name: myapp-pod
          image: "imagerepo"
          resources:
            limits:
              cpu: 500m
              memory: 800Mi
            requests:
              cpu: 500m
              memory: 800Mi

Solution

  • $ cat tst.awk
    { print }
    sub(/serviceAccountName:.*/,"") && (++cnt1 == 1) {
        print $0 "imagePullSecrets:"
        print $0 "  - name: imagepullsecret"
    }
    sub(/resources:.*/,"") && (++cnt2 == 11) {
        print $0 "  limits:"
        print $0 "    cpu: 500m"
        print $0 "    memory: 800Mi"
    }
    

    $ awk -f tst.awk file
    spec:
      replicas: 1
      strategy:
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 0
      selector:
        matchLabels:
          app.kubernetes.io/name: myapp
          app.kubernetes.io/instance: myapp
      template:
        metadata:
          annotations:
            checksum/config: 2cee4a874d2afd91d92301f15efece5afbca3abc63ba3b2b
            checksum/tls-secrets: 649c0580ebbcf3ae194d17b8ac4cc2f1cda33f145da9764
          labels:
            app.kubernetes.io/name: myapp
            app.kubernetes.io/instance: myapp
        spec:
          serviceAccountName: myapp-acc
          imagePullSecrets:
            - name: imagepullsecret
          containers:
            - name: myapp-pod
              image: "imagerepo"
              resources:
                limits:
                  cpu: 500m
                  memory: 800Mi
                requests:
                  cpu: 500m
                  memory: 800Mi
    

    I added the ++cnt tests after I initially ran the code on the provide sample input since that input doesn't provide a way to test that functionality.