Yaml files can be surprisingly lenient in what can be parsed as a yaml file. A reasonable way of validation a yaml file is to ensure the top level is a map or array (although it is valid yaml to have scalars at the top level, but often this is not what you want). This can be done by:
yq e --exit-status 'tag == "!!map" or tag== "!!seq"' file.txt > /dev/null
The most reliable way to set the contents from another file is to load it in as a yaml file, and use the assign and fileIndex(fi) operator. Note that the file will need to be valid yaml, however, strings, numbers and JSON are all valid yaml. As you are working with multiple files, you will need to use the eval-all
command. Note that as we don't want to output the second file, we have a final fi
filter to select the first.
yq ea 'select(fi==0).a = select(fi==1) | select(fi==0)' file1.yaml otherFile.txt
To create a new yaml
file simply:
yq e -n '.someNew="content"' > newfile.yml
Note that running expressions against blank files does not work, because the file is empty, there are no matches for yq
to run through the expression pipeline and so nothing happens.
The merge functionality from yaml v1.1 (e.g. <<:
has actually been removed in the 1.2 spec. Thankfully, yq
underlying yaml parser still supports that tag - and it's extra nice in that it explicity puts the !!merge
tag on key of the map entry. This tag tells other yaml parsers that this entry is a merge entry, as opposed to a regular string key that happens to have a value of <<:
. This is backwards compatible with the 1.1 spec of yaml, it's simply an explicit way of specifying the type (for instance, you can use a !!str
tag to enforce a particular value to be a string.
Although this does affect the readability of the yaml to humans, it still works and processes fine with various yaml processors.