Search code examples
yamlyq

Using yq delete list item and parent node if list becomes empty


I have fields with example values.

EDIT: there are other nodes at the root level (siblings of fields) that I need to retain, too.

  • If a value is empty, I want to remove the parent list item
  • If there are no examples left, I want to remove the entire examples node
  • The examples may have other fields of their own, but I just want to follow the two rules above no matter what

Input

project: people_ages
fields:
  first_name:
    examples:
      - value: Jon
        comment: A very common name
  last_name:
    examples:
      - value: ''
        comment: Where is his last name?
  age:
    examples:
      - value: 22
        comment: Just got out of college
      - value:
        comment: Not sure about his age

Desired output

project: people_ages
fields:
  first_name:
    examples:
      - value: Jon
        comment: A very common name
  last_name:
  age:
    examples:
      - value: 22
        comment: Just got out of college

Using Go version of yq - mikefarah/yq


Solution

  • You can use the combination of to_entries/from_entries builtins, with map and select

    yq '.fields | to_entries | map(select(.value.examples[].value != "")) | 
            map(select(.value.examples | length >0)) | from_entries' yaml
    

    The to_entries method converts the objects into a key/value pair with key and value prefixed as key names respectively and from_entries does the opposite of it. Between the two, the logic to exclude the objects containing .value as empty string is applied. And when the previous transformation is complete, we now exclude at the .examples level to consider those objects that have non-zero entries.


    Per updated requirement added to the question to retain other fields and keeping the original YAML structure intact, suggest using the update select operator |=

    yq '.fields |= (to_entries | map(select(.value.examples[].value != "")) | 
            map(select(.value.examples | length >0)) | from_entries)' yaml