skip to Main Content

In a file I want to append a string after the specific segment with key "sys-mgmt-agent".
This is the file content:

  sys-mgmt-agent:
    networks:
     edgex-network:
       aliases:
           - edgex-sys-mgmt-agent
    depends_on:
      - redis
    volumes:
      - /proc/uptime:/proc/uptime
      - /var/log/auth.log:/var/log/auth.log
      - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z

  edge-orchestrator:
    networks:
     edgex-network:
       aliases:
           - edgex-sys-mgmt-agent
    depends_on:
      - redis
    volumes:
      - /proc/uptime:/proc/uptime
      - /var/log/auth.log:/var/log/auth.log
      - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z

This is the expected result:

  sys-mgmt-agent:
    networks:
     edgex-network:
       aliases:
           - edgex-sys-mgmt-agent
    depends_on:
      - redis
    volumes:
      - /proc/uptime:/proc/uptime
      - /var/log/auth.log:/var/log/auth.log
      - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z
    MY STRING

  edge-orchestrator:
    networks:
     edgex-network:
       aliases:
           - edgex-sys-mgmt-agent
    depends_on:
      - redis
    volumes:
      - /proc/uptime:/proc/uptime
      - /var/log/auth.log:/var/log/auth.log
      - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z

I found the segment using sed command: sed -n '/sys-mgmt-agent:/,/^s*$/p' <file> but I can’t append my string.

3

Answers


  1. Assumptions:

    • OP insists on using basic commands avialable under bash
    • input is nicely formatted as presented
    • if sys-mgmt-agent: shows up more than once the desired string is to be appended to each segment
    • there is at least one blank line between segments

    One awk solution:

    $ mystring="MY STRING"                         # string to be appended to segment
    $ awk -v ms="${mystring}" '                    # pass ${mystring} as awk variable "ms" 
    /sys-mgmt-agent:/ { foundit=1 }                # if line contains "sys-mgmt-agent:" then set our flag
    /^$/ && foundit { printf "    %snn", ms      # if blank line and foundit=1 then print our string plus a new blank line
                      foundit=0                    # reset our flag
                      next                         # go to next input line
                    }
                    { print }                      # print all other lines as is
    ' mydata                                       # assuming input data is in file named "mydata"
    

    The above generates:

    sys-mgmt-agent:
      networks:
       edgex-network:
         aliases:
             - edgex-sys-mgmt-agent
      depends_on:
        - redis
      volumes:
        - /proc/uptime:/proc/uptime
        - /var/log/auth.log:/var/log/auth.log
        - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z
      MY STRING
    
    edge-orchestrator:
      networks:
       edgex-network:
         aliases:
             - edgex-sys-mgmt-agent
      depends_on:
        - redis
      volumes:
        - /proc/uptime:/proc/uptime
        - /var/log/auth.log:/var/log/auth.log
        - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z
    
    Login or Signup to reply.
  2. A sed idea that builds on OPs sed attempt:

    $ mystring='MY STRING'
    $ sed "/sys-mgmt-agent:/,/^$/{/^$/i    ${mystring}
    }" mydata
    

    Where:

    • /sys-mgmt-agent/,/^$/ – range to search for
    • {...} – commands to apply to matching range
    • /^$/i ${mystring} – at the blank line insert a new line " MY STRING"

    NOTE: The i ${mystring} can’t have anything after it on the same line hence the 2-line solution; I’m open to suggestions on how to collapse this into a single line.


    UPDATE: @potong’s suggestion for using -e flags to piece together a one-line solution works with the addition of double quotes around ${mystring}:

    $ mystring='MY STRING'
    $ sed -e '/sys-mgmt-agent:/,/^$/{/^$/i    '"${mystring}" -e '}' mydata
    

    The above generates:

      sys-mgmt-agent:
        networks:
         edgex-network:
           aliases:
               - edgex-sys-mgmt-agent
        depends_on:
          - redis
        volumes:
          - /proc/uptime:/proc/uptime
          - /var/log/auth.log:/var/log/auth.log
          - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z
        MY STRING
    
      edge-orchestrator:
        networks:
         edgex-network:
           aliases:
               - edgex-sys-mgmt-agent
        depends_on:
          - redis
        volumes:
          - /proc/uptime:/proc/uptime
          - /var/log/auth.log:/var/log/auth.log
          - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z
    
    Login or Signup to reply.
  3. This might work for you (GNU sed):

    sed '/sys-mgmt-agent:/{:a;/:$/h;n;/S/{$!ba;p};x;s/S.*/MY STRING/p;x;$d}' file
    

    N.B. if MY STRING contains /‘s these must be escaped/quoted i.e. /. This also indents to the depth of the last stanza.

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