Search code examples
yamlyq

Is it possible to insert an element into a middle of array in YAML using YQ?


I have a YAML document like this

    
services:
  - name: newlogd
    image: NEWLOGD_TAG
    cgroupsPath: /eve/services/newlogd
    oomScoreAdj: -999
  - name: edgeview
    image: EDGEVIEW_TAG
    cgroupsPath: /eve/services/eve-edgeview
    oomScoreAdj: -800
  - name: debug
    image: DEBUG_TAG
    cgroupsPath: /eve/services/debug
    oomScoreAdj: -999
  - name: wwan
    image: WWAN_TAG
    cgroupsPath: /eve/services/wwan
    oomScoreAdj: -999

I need to insert a new object AFTER given element e.g. with name == "edgeview". so the output looks like this


services:
  - name: newlogd
    image: NEWLOGD_TAG
    cgroupsPath: /eve/services/newlogd
    oomScoreAdj: -999
  - name: edgeview
    image: EDGEVIEW_TAG
    cgroupsPath: /eve/services/eve-edgeview
    oomScoreAdj: -800
  - name: new_element_name
    image: new_element_image
  - name: debug
    image: DEBUG_TAG
    cgroupsPath: /eve/services/debug
    oomScoreAdj: -999
  - name: wwan
    image: WWAN_TAG
    cgroupsPath: /eve/services/wwan
    oomScoreAdj: -999

I couldn't find anything about it in YQ documentation. Is it even possible using YQ?

UPDATE: I'm using YQ https://github.com/mikefarah/yq version 4.28.1. I was not aware that there several tools with the same name.


Solution

  • Using the YAML processor yq:

    yq --arg insertAfter edgeview -y '
       limit(1; .services | to_entries[] | select(.value.name == $insertAfter) | .key + 1) as $idx
       | .services |= .[0:$idx] +
                      [{name: "new_element_name", image: "new_element_image"}] +
                      .[$idx:]'
    

    In the first line, the index of the element to be inserted after is determined and stored into $idx. If you have several elements with the same name, only the first match is used (limit). In the following filter step, $idx is used to split the array and insert the new element at the desired position.

    Output

    services:
      - name: newlogd
        image: NEWLOGD_TAG
        cgroupsPath: /eve/services/newlogd
        oomScoreAdj: -999
      - name: edgeview
        image: EDGEVIEW_TAG
        cgroupsPath: /eve/services/eve-edgeview
        oomScoreAdj: -800
      - name: new_element_name
        image: new_element_image
      - name: debug
        image: DEBUG_TAG
        cgroupsPath: /eve/services/debug
        oomScoreAdj: -999
      - name: wwan
        image: WWAN_TAG
        cgroupsPath: /eve/services/wwan
        oomScoreAdj: -999