| name | cli-yq |
| description | Covers effective use of yq for reading, writing, and transforming YAML, JSON, XML, TOML, and CSV files. Activates when the user asks about yq, editing YAML configs, patching Kubernetes manifests, merging compose files, or converting between structured data formats.
|
yq — YAML/JSON/XML/TOML Processor
Repo: https://github.com/mikefarah/yq
Portable command-line YAML processor. Uses jq-like syntax to read, update,
merge, and convert YAML (and JSON, XML, TOML, CSV). The go-to tool for
patching Kubernetes manifests, Docker Compose files, and CI/CD configs in
scripts without a full templating engine.
When to Activate
Manual triggers:
- "How do I use yq?"
- "Edit a YAML file from the command line"
- "Patch a Kubernetes manifest"
- "Convert YAML to JSON"
Auto-detect triggers:
- User wants to read or update YAML config without opening an editor
- User is scripting Kubernetes manifest generation or patching
- User wants to merge multiple YAML files
- User wants to substitute environment variables into YAML
- User needs to convert between YAML, JSON, TOML, or XML
Key Commands
Running yq
yq '.' file.yaml
yq -o=json '.' file.yaml
yq -o=yaml '.' file.json
yq -P '.' file.json
yq -i '.' file.yaml
yq -e '.key' file.yaml
yq --no-colors '.' file.yaml
yq '.' *.yaml
cat file.yaml | yq '.'
Reading Values
yq '.key' file.yaml
yq '.a.b.c' file.yaml
yq '.items[0]' file.yaml
yq '.items[-1]' file.yaml
yq '.items[0].name' file.yaml
yq '.items[] | .name' file.yaml
yq 'keys' file.yaml
yq '.map | keys' file.yaml
yq 'length' file.yaml
yq '.items | length' file.yaml
yq '. | type' file.yaml
Updating Values (in-place)
yq -i '.image.tag = "v2.0.0"' deployment.yaml
yq -i '.replicas = 3' deployment.yaml
yq -i '.env[] |= . + " --verbose"' config.yaml
yq -i '.items += ["new-item"]' file.yaml
yq -i 'del(.obsoleteKey)' file.yaml
yq -i 'del(.items[2])' file.yaml
yq -i '.metadata.labels.version = env(VERSION)' manifest.yaml
Adding and Deleting
yq '. + {"newKey": "value"}' file.yaml
yq '.items += [{"name": "extra"}]' file.yaml
yq 'del(.secret)'
yq 'del(.items[] | select(.name == "remove-me"))'
yq '.items[] |= select(.active)'
Array Operations
yq '.items[]' file.yaml
yq '.items | length' file.yaml
yq '.items[0:3]' file.yaml
yq '.items | sort' file.yaml
yq '.items | sort_by(.name)' file.yaml
yq '.items | reverse' file.yaml
yq '.items | unique' file.yaml
yq '.items | unique_by(.id)' file.yaml
yq '[.items[] | select(.enabled)]' file.yaml
yq '.items | map(. * 2)' file.yaml
yq '.items | map(select(. > 5))' file.yaml
String Operations
yq '.name | upcase' file.yaml
yq '.name | downcase' file.yaml
yq '.name | split(" ")' file.yaml
yq '.parts | join("-")' file.yaml
yq '.name | test("^prefix")' file.yaml
yq '.name | sub("old","new")' file.yaml
yq '.name | gsub("old","new")' file.yaml
yq '"prefix-" + .name' file.yaml
yq '.items[] | .name + "=" + .value' file.yaml
Format Conversion
yq -o=json '.' file.yaml
yq -o=yaml '.' file.json
yq '.' file.json
yq -o=toml '.' file.yaml
yq '.' file.toml
yq -o=xml '.' file.yaml
yq '.' file.xml
yq -o=csv '.items[] | [.name, .count]' file.yaml
yq -o=tsv '.items[] | [.name, .value]' file.yaml
Environment Variable Substitution
VERSION=v2.1.0 yq '.image.tag = env(VERSION)' deployment.yaml
APP_PORT=8080 yq -i '.service.port = env(APP_PORT) | .service.port |= . + 0' svc.yaml
yq '.spec.template.spec.containers[].image |= sub("IMAGE_TAG"; env(TAG))' deploy.yaml
yq '.' template.yaml | envsubst
Multi-Document YAML
yq '.' multi.yaml
yq 'select(document_index == 0)' multi.yaml
yq 'select(.kind == "Deployment")' manifests.yaml
yq '. | select(.kind == "Service") | .metadata.name' k8s/*.yaml
yq 'select(document_index == 0)' multi.yaml > first.yaml
yq 'select(document_index == 1)' multi.yaml > second.yaml
Merging Files
yq '. *+ load("overrides.yaml")' base.yaml
yq '. *d load("patch.yaml")' base.yaml
yq '. *+ {"items": [{"extra": true}]}' file.yaml
cat *.yaml | yq '.'
yq -s '.' *.yaml
Advanced Patterns
Kubernetes Manifests
yq -i '.spec.template.spec.containers[].image |= sub(":.*$"; ":" + env(TAG))' deploy.yaml
yq -i '
.spec.template.spec.containers[0].resources = {
"requests": {"cpu": "100m", "memory": "128Mi"},
"limits": {"cpu": "500m", "memory": "512Mi"}
}
' deploy.yaml
yq -i 'select(.kind == "Deployment") |
.metadata.annotations["deploy-time"] = env(DEPLOY_TIME)' k8s/*.yaml
yq '.spec.template.spec.containers[].image' k8s/*.yaml | sort | uniq
yq 'select(. != null) | .kind + "/" + .metadata.name' k8s/*.yaml
Docker Compose
yq -i ".services.api.image = \"myapp:${TAG}\"" docker-compose.yml
yq -i '.services.api.environment += ["NEW_VAR=value"]' docker-compose.yml
yq -i '.services.worker.deploy.replicas = 4' docker-compose.yml
yq '. *+ load("docker-compose.override.yml")' docker-compose.yml
CI/CD Configs
yq -i '.jobs.test.strategy.matrix.node += ["20"]' .github/workflows/ci.yml
yq 'keys | .[]' .gitlab-ci.yml
yq '.orbs | to_entries[] | "\(.key): \(.value)"' .circleci/config.yml
yq -i '.ingress.hosts[0].host = "api.example.com"' values.yaml
YAML Anchors and Aliases
yq --no-doc-separator '.' file-with-anchors.yaml
yq 'explode(.)' file-with-anchors.yaml
yq '. | ... comments=""' file.yaml
Combining with Shell Loops
for f in k8s/*.yaml; do
yq -i '.metadata.labels.env = "production"' "$f"
done
for svc in $(yq '.services | keys | .[]' docker-compose.yml); do
echo "Service: $svc"
done
yq -e '.name and .version and .author' package.yaml || echo "Missing required fields"
Practical Examples
Daily Config Workflows
yq '.database.host' config.yaml
yq -i '.version = "2.0.0"' package.yaml
yq '.env | to_entries[] | "export \(.key)=\(.value)"' config.yaml | source
curl -s https://api.example.com/resource | yq -P '.'
Kubernetes Rollout Helper
yq ".spec.template.spec.containers[0].image = \"myapp:${TAG}\"" deploy.yaml \
| kubectl apply -f -
Diff Two YAML Files
diff <(yq -o=json 'sort_keys(..)' a.yaml) <(yq -o=json 'sort_keys(..)' b.yaml)
Chaining with Other Skills
- jq (cli-jq): Convert YAML → JSON with
yq -o=json, pipe to jq for complex queries; or reverse with yq -o=yaml
- kubectl:
yq patches manifests, kubectl apply -f - consumes them — the classic GitOps combo
- gh (cli-gh): Extract workflow/action config values with yq, use gh to trigger workflow runs with the updated params
- envsubst:
yq '.' template.yaml | envsubst for full shell-style ${VAR} substitution in YAML templates