Skip to content
Latchkey

yq: Handle Multi-Document YAML Files

yq treats each --- separated block as its own document, evaluating per document with eval or all together with eval-all.

Kubernetes manifests routinely bundle several resources with --- separators. yq can edit each one independently, pick one out, or split them into files.

What it does

A --- separator starts a new YAML document. yq eval runs the expression once per document; documentIndex (alias di) gives the zero-based position. select(documentIndex == n) keeps one document; eval-all is needed when an expression must see all documents at once.

Common usage

Terminal
# edit a field in every document
yq -i '.metadata.namespace = "prod"' manifests.yaml
# keep only the Service document
yq 'select(.kind == "Service")' manifests.yaml
# print which document index each kind is at
yq '[documentIndex, .kind]' manifests.yaml

Multi-doc tools

Expression / flagWhat it does
---Document separator in YAML
documentIndex (di)Zero-based index of the current document
select(documentIndex == 0)Keep the first document
-N / --no-docSuppress the --- separators in output
-s / --split-expSplit each document into its own file
eval-allBring all documents into one scope

In CI

To patch the image in just the Deployment of a bundled manifest: yq -i '(select(.kind=="Deployment") | .spec.template.spec.containers[0].image) = strenv(IMG)' manifests.yaml. The select keeps the edit scoped to the right document.

Common errors in CI

Converting a multi-doc file to JSON yields several top-level JSON objects, which most JSON parsers reject; select a single document or use eval-all with [...]. Output keeping unexpected --- lines means you want -N. Python yq reads only the first document by default unless you slurp, another behavioral tell between the two implementations.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →