Tips, Tricks, Troubleshooting

Validating yaml files

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

Set contents from another file

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

Creating a new file / working with blank documents

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.

yq adds a !!merge tag automatically

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.