logo

yq Cheatsheet

yq: a command-line YAML processor.

Installation

# macOS (Homebrew)
brew install yq

# Linux (Snap)
snap install yq

# Or download the binary from the GitHub releases page:
# https://github.com/mikefarah/yq/releases
wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq && chmod +x /usr/bin/yq

# Check version
yq -V

Basic Syntax

The fundamental pattern is: yq [flags] '<expression>' [input-file.yaml]

  • If no file is given, yq reads from stdin.
  • The expression is a path or operation to perform on the YAML.

e.g.

$ yq '.name' file.yaml
$ cat file.yaml | yq '.a.b[0].c'

Core Flags

Flag Long Flag Description
-i --inplace In-place edit. Modifies the file directly instead of printing to stdout.
-o --output-format Output format. Can be yaml (default), json (or j), props, xml, csv, tsv.
-n --null-input Creates a new YAML document from scratch using the expression.
-P --prettyPrint Pretty print output.
-C --colors Force color output (useful in scripts).
-Y --yaml-output (Default) Alias for -o yaml.
-j --tojson Alias for -o json.

1. Reading Values (Querying)

Let's use this sample.yaml for all examples:

# sample.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: web
          image: 'nginx:1.21'
          ports:
            - containerPort: 80
        - name: sidecar
          image: 'prom/graph-exporter:v0.1.0'

Read a Specific Field

# Read a top-level key
yq '.kind' sample.yaml
# Output: Deployment

# Read a nested key
yq '.spec.replicas' sample.yaml
# Output: 3

Read from an Array**

# Read the first item in an array (zero-indexed)
yq '.spec.template.spec.containers[0].name' sample.yaml

# Output: web

# Get the last item in an array
yq '.spec.template.spec.containers[-1].image' sample.yaml

# Output: "prom/graph-exporter:v0.1.0"

Get All Values from an Array/Map (Iterating)

# Get all container names
yq '.spec.template.spec.containers[].name' sample.yaml
# Output:
# web
# sidecar

# Get all labels
yq '.metadata.labels.*' sample.yaml
# Output: my-app

2. Writing & Updating Values

Update an Existing Value

# Change the number of replicas (prints to stdout)
yq '.spec.replicas = 5' sample.yaml

# Update the image tag IN-PLACE, (`-i` for in-place)
yq -i '.spec.template.spec.containers[0].image = "nginx:1.22"' sample.yaml
yq -i '.a.b[0].c = "cool"' file.yaml

Add a New Field

# Add a new label
yq '.metadata.labels.version = "v1"' sample.yaml

# Add a new annotation block
yq '.metadata.annotations = {"comment": "added by yq"}' sample.yaml

Add to an Array (Appending)

# Add a new container to the list
yq '.spec.template.spec.containers += [{"name": "new-container", "image": "redis"}]' sample.yaml

Create a New YAML File

Use the -n (null-input) flag.

yq -n '.a.b = "hello" | .a.c = [1, 2]'
# Output:
# a:
#   b: hello
#   c:
#     - 1
#     - 2

3. Advanced Operations & Operators

Piping (|)

Chain multiple operations together, just like in jq.

# Get the first container, then get its name
yq '.spec.template.spec.containers[0] | .name' sample.yaml
# Output: web

Filtering with select

Select elements that match a condition.

# Find the container with the name 'sidecar' and get its image
yq '.spec.template.spec.containers[] | select(.name == "sidecar") | .image' sample.yaml
# Output: "prom/graph-exporter:v0.1.0"

Merging (*)

Deeply merge two YAML files. file2.yaml will overwrite values in file1.yaml.

# base.yaml
a:
  b: 1
  c: 2

# override.yaml
a:
  b: 99 # This will overwrite
  d: 3  # This will be added

# The 'eval-all' command is used for multiple files
yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' base.yaml override.yaml
# Output:
# a:
#   b: 99
#   c: 2
#   d: 3

Working with Multiple Documents (---)

If a YAML file contains multiple documents separated by ---.

# Get the 'kind' from the second document (zero-indexed)
yq 'select(documentIndex == 1) | .kind' multi.yaml

Other Useful Operators

  • keys: Get the keys of a map. yq '.metadata.labels | keys' sample.yaml
  • del(...): Delete a key. yq 'del(.spec.replicas)' sample.yaml
  • has(...): Check if a map has a key. yq '.spec | has("replicas")' sample.yaml -> true
  • //: Provide a default value. yq '.spec.nonExistentKey // "default"' sample.yaml -> "default"

4. Practical Recipes

# Get the image tag of the first container
yq '.spec.template.spec.containers[0].image' deployment.yaml

# Update the image tag of a specific container in-place
yq -i '(.spec.template.spec.containers[] | select(.name == "web")).image = "nginx:latest"' deployment.yaml

# Convert YAML to JSON
yq -o json '.' config.yaml
# Short alias: yq '.' config.yaml -j

yq -o json foo.yaml > foo.json

# Convert JSON to YAML
yq -o yaml '.' config.json
# Short alias: cat config.json | yq -P

# List all container images in a Kubernetes Deployment
yq '.spec.template.spec.containers[].image' deployment.yaml

# Add a new annotation to a Kubernetes resource
yq -i '.metadata.annotations."kubernetes.io/change-cause" = "Updated by script"' deployment.yaml

Delete multiple fields:

$ cat obj_backup.yaml | yq 'del(.status, .metadata.creationTimestamp, .metadata.resourceVersion, .metadata.uid, .metadata.generation)' > obj.yaml

Select from a list, by name:

$ yq '.[] | select(.name == "Foo")' example.yml

Increment numBuckets:

$ yq '(.[] | select(.name == "Foo") | .numBuckets) |= . + 1' sample.yml

|= is the operator that updates fields relative to their own value, which is referenced as dot (.)

Sort an array by a field

$ yq '.myArray |= sort_by(.numBuckets)' sample.yml