awkyaml

How to split a YAML into multiple files with a proper name


I have a valid YAML:

---
name: first
metadata: a
---
name: second
metadata: b
---
name: third
metadata: c

How can I split it using a one-liner AWK script in files first.yaml, second.yaml and third.yaml? Solution needs to work with any name.

Just splitting the file works but I can't figure out how to add proper file names instead of line numbers (NR):

awk '/\-\-\-/{f=NR".yaml"}; {print >f}'

Solution

  • EDIT: Adding 1 more solution.

    awk '
    /name:/{
      close(file)
      file=$NF".yaml"
    }
    file!="" && !/^--/{
      print > (file)
    }
    ' Input_file
    


    Could you please try following.

    awk '
    prev!=file{
      close(prev)
    }
    /name:/{
      file=$NF".yaml"
    }
    file!="" && !/^--/{
      print > (file)
      prev=file
    }
    ' Input_file
    

    Sample output file will be:

    cat first.yaml
    name: first
    metadata: a
    

    Explanation: Adding detailed explanation for above code.

    awk '                     ##Starting awk program from here.
    prev!=file{               ##Checking condition if prev is NOT equal to file variable then do following.
      close(prev)             ##Closing output file, to avoid too many files opened in back-end by mentioning close(prev) command here.
    }                         ##Closing condition prev!=file here.
    /name:/{                  ##Checking condition if line has string name: in it then do following.
      file=$NF".yaml"         ##Creating variable named file whose value is $NF(last field of current line) .yaml
    }                         ##Closing name: condition here.
    file!="" && !/^--/{       ##Checking condition if variable file is NOT NULL AND line is NOT starting with dash then do following.
      print > (file)          ##Printing current line into output file whose name is there in file variable.
      prev=file               ##Setting prev variable whose value is variable file here.
    }                         ##Closing BLOCK for file!="" && !/^--/ condition here.
    '  Input_file             ##Mentioning Input_file name here.