Saltar a contenido

Hoja de referencia de yq - Procesador YAML/JSON/XML

Instalación

Platform Comando
Ubuntu/Debian wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq && chmod +x /usr/local/bin/yq
Ubuntu (PPA) sudo add-apt-repository ppa:rmescandon/yq && sudo apt update && sudo apt install yq
macOS (Homebrew) brew install yq
macOS (MacPorts) sudo port install yq
Windows (Chocolatey) choco install yq
Windows (Scoop) scoop install yq
Snap snap install yq
Go go install github.com/mikefarah/yq/v4@latest
Docker docker run --rm -v "${PWD}":/workdir mikefarah/yq
Alpine Linux apk add yq
Arch Linux yay -S yq
Verify Installation yq --version
## Comandos Básicos - Lectura y Visualización
Comando Descripción
yq '.' file.yaml Mostrar archivo YAML completo (impresión elegante)
yq '.name' file.yaml Leer un valor de campo específico
yq '.metadata.name' file.yaml Leer campo anidado usando notación de punto
yq '.items[0]' file.yaml Acceder al primer elemento de un array
yq '.items[*]' file.yaml Acceder a todos los elementos de un array
yq '.items[]' file.yaml Iterar a través de elementos de array
yq '.items[].name' file.yaml Extraer campo específico de todos los elementos del array
yq '.items[-1]' file.yaml Acceder al último elemento de un array
yq '.items[1:3]' file.yaml Slice de array (elementos 1 y 2)
cat file.yaml \ | yq '.spec' Leer desde stdin
yq -r '.name' file.yaml Salida de cadena sin procesar (sin comillas)
yq '.items \ | length' file.yaml Obtener la longitud de un array u objeto
yq 'keys' file.yaml Enumerar todas las claves de nivel superior
yq '.[] \ | keys' file.yaml Enumerar claves de objetos anidados
## Comandos Básicos - Escritura y Actualización
Comando Descripción
yq '.name = "new-value"' file.yaml Actualizar un campo (imprime en stdout)
yq -i '.name = "new-value"' file.yaml Actualizar campo en su lugar (modifica archivo)
yq '.spec.replicas = 3' file.yaml Actualizar valor anidado
yq '.items[0].name = "updated"' file.yaml Actualizar elemento de array
yq '.newField = "value"' file.yaml Crear nuevo campo
yq '.metadata.labels.env = "prod"' file.yaml Crear campo anidado
yq 'del(.fieldName)' file.yaml Eliminar un campo
yq 'del(.metadata.annotations)' file.yaml Eliminar campo anidado
yq 'del(.items[0])' file.yaml Eliminar elemento de array
yq '.items += {"name": "new"}' file.yaml Añadir al array
yq '.items = []' file.yaml Limpiar array
yq '.count += 1' file.yaml Incrementar valor numérico
yq '.total = .price * .quantity' file.yaml Operaciones aritméticas
## Uso Avanzado - Filtrado y Selección
Comando Descripción
yq '.items[] \ | select(.kind == "Pod")' file.yaml Filtrar elementos por condición
yq '.items[] \ | select(.kind == "Pod" and .status == "Running")' file.yaml Múltiples condiciones (AND)
yq '.items[] \ | select(.kind == "Pod" or .kind == "Service")' file.yaml Condiciones múltiples (OR)
yq '.items[] \ | seleccionar(.nombre \ | test("^prod-"))' file.yaml Coincidencia de patrones con regex
yq '.items[] \ | select(has("metadata"))' file.yaml Verificar si el campo existe
yq '.items[] \ | select(.replicas > 3)' file.yaml Comparación numérica
yq '.items[] \ | seleccionar(.etiquetas \ | contains(["prod"]))' file.yaml Comprobación de contiene array
yq '.items[] \ | select(.name != null)' file.yaml Filtrar valores nulos
yq '.[] \ | select(tag == "!!str")' file.yaml Filtrar por tipo de etiqueta YAML
## Uso Avanzado - Operaciones con Arreglos
Comando Descripción
yq '.items \ | = sort_by(.name)' file.yaml Ordenar array por campo
yq '.items \ | = sort_by(.metadata.creationTimestamp)' file.yaml Ordenar por campo anidado
yq '.items \ | = reverse' file.yaml Invertir orden de array
yq '.tags \ | unique' file.yaml Obtener valores únicos de un array
yq '.items \ | flatten' file.yaml Aplanar arrays anidados
yq '.items \ | group_by(.kind)' file.yaml Agrupar elementos de array
yq '.items \ | map(.name)' file.yaml Mapear array para extraer valores
yq '.items \ | map(select(.active))' file.yaml Filtrar y mapear combinados
yq '.items = .items + .newItems' file.yaml Concatenar arrays
yq '.items \ | = unique_by(.name)' file.yaml Eliminar duplicados por campo
yq '[.items[].name]' file.yaml Recopilar valores en un nuevo array
## Uso Avanzado - Fusión y Combinación
Comando Descripción
yq ea 'select(fi == 0) * select(fi == 1)' f1.yaml f2.yaml Fusión profunda de dos archivos (f2 sobrescribe f1)
yq ea '. as $item ireduce ({}; . * $item)' *.yaml Combinar varios archivos
yq ea 'select(fi == 0) *+ select(fi == 1)' f1.yaml f2.yaml Fusionar con concatenación de array
yq ea '[.]' file1.yaml file2.yaml Combinar archivos en un array
yq '.config = load("config.yaml")' file.yaml Cargar y combinar archivo externo
yq '.spec.template = load("template.yaml").spec' file.yaml Cargar ruta específica desde archivo
yq ea 'select(fi == 0) *d select(fi == 1)' f1.yaml f2.yaml Fusión profunda con eliminación
## Uso Avanzado - Operaciones con Cadenas
Comando Descripción
yq '.fullName = .firstName + " " + .lastName' file.yaml Concatenación de cadenas
yq '.name \ | = upcase' file.yaml Convertir a mayúsculas
yq '.name \ | = downcase' file.yaml Convertir a minúsculas
yq '.name \ | = trim' file.yaml Eliminar espacios en blanco
yq '.text \ | = sub("old", "new")' file.yaml Reemplazar primera ocurrencia
yq '.text \ | = gsub("old", "new")' file.yaml Reemplazar todas las ocurrencias
yq '.path \ | split("/")' file.yaml Dividir cadena en array
yq '.tags \ | join(", ")' file.yaml Unir array en cadena
yq '.name \ | length' file.yaml Longitud de cadena
yq '.text \ | contains("substring")' file.yaml Verificar si la cadena contiene subcadena
## Uso Avanzado - Conversión de Formatos
Comando Descripción
yq -o=json '.' file.yaml Convertir YAML a JSON
yq -P '.' file.json Convertir JSON a YAML
yq -o=xml '.' file.yaml Convertir YAML a XML
yq -p=xml '.' file.xml Convertir XML a YAML
yq -o=csv '.items[]' file.yaml Convertir YAML a CSV
yq -o=props '.' file.yaml Convertir YAML a formato properties
yq -o=json -I=4 '.' file.yaml JSON con sangría personalizada
yq -o=yaml --yaml-output-version=1.1 '.' file.yaml Especificar versión YAML
yq -p=csv -o=json '.' file.csv Convertir CSV a JSON a través de YAML
## Configuración

Opciones de Línea de Comandos

# Input/Output format options
-p, --input-format string    Input format (yaml/json/xml/csv/props)
-o, --output-format string   Output format (yaml/json/xml/csv/props)
-P, --prettyPrint           Pretty print (shorthand for -o=yaml)

# Modification options
-i, --inplace               Edit file in place
-I, --indent int            Indentation (default 2)

# Processing options
-e, --exit-status           Exit with status code based on result
-n, --null-input            Don't read input, start with null
-N, --no-colors             Disable colored output
-C, --colors                Force colored output

# Multiple file options
ea, eval-all                Evaluate all files together

Sintaxis de Expresiones

# Basic path expressions
.field                      # Access field
.nested.field              # Nested access
.[0]                       # Array index
.[]                        # Array iteration
.*                         # All fields

# Operators
=                          # Assignment
|=                         # Update assignment
+=                         # Append/increment
*                          # Multiply/merge
+                          # Add/concatenate
-                          # Subtract
//                         # Alternative operator (default value)

# Functions
select()                   # Filter
map()                      # Transform array
has()                      # Check existence
keys                       # Get keys
length                     # Get length
sort_by()                  # Sort array
group_by()                 # Group array
unique                     # Remove duplicates

Variables de Entorno

# Use environment variables in expressions
export APP_NAME="my-app"
yq '.name = env(APP_NAME)' file.yaml

# With default value
yq '.name = (env(NAME) // "default")' file.yaml

# String interpolation
yq '.message = "Hello " + env(USER)' file.yaml

Casos de Uso Comunes

Caso de Uso 1: Actualizar Réplicas de Despliegue de Kubernetes

# Single deployment
yq -i '.spec.replicas = 5' deployment.yaml

# Multiple deployments in one file
yq -i '(.spec.replicas | select(. != null)) = 5' deployments.yaml

# Conditionally update specific deployment
yq -i '(select(.metadata.name == "api-server") | .spec.replicas) = 10' deployment.yaml

# Update all deployments in multiple files
yq -i '.spec.replicas = 3' k8s/*.yaml

Caso de Uso 2: Fusionar Archivos de Configuración

# Merge base config with environment-specific overrides
yq ea 'select(fi == 0) * select(fi == 1)' base-config.yaml prod-config.yaml > final-config.yaml

# Merge multiple environment files
yq ea '. as $item ireduce ({}; . * $item)' base.yaml dev.yaml local.yaml > merged.yaml

# Merge with array concatenation
yq ea 'select(fi == 0) *+ select(fi == 1)' config1.yaml config2.yaml > combined.yaml

Caso de Uso 3: Extraer y Transformar Datos

# Extract all container images from Kubernetes manifests
yq '.spec.template.spec.containers[].image' deployment.yaml

# Get all service names and ports
yq '.items[] | select(.kind == "Service") | .metadata.name + ":" + (.spec.ports[0].port | tostring)' services.yaml

# Create summary report
yq '.items[] | {"name": .metadata.name, "kind": .kind, "namespace": .metadata.namespace}' resources.yaml -o=json

Caso de Uso 4: Actualizaciones Masivas en Múltiples Archivos

# Add label to all resources
find . -name "*.yaml" -exec yq -i '.metadata.labels.environment = "production"' {} \;

# Update image tag in all deployments
yq -i '(.spec.template.spec.containers[].image | select(. == "*:latest")) |= sub(":latest", ":v1.2.3")' k8s/**/*.yaml

# Add annotation to specific resources
yq -i 'select(.kind == "Service") | .metadata.annotations."prometheus.io/scrape" = "true"' *.yaml

Caso de Uso 5: Configuración de Pipeline CI/CD

# Update version in multiple config files
export VERSION="2.1.0"
yq -i '.version = env(VERSION)' chart/Chart.yaml
yq -i '.image.tag = env(VERSION)' values.yaml

# Inject secrets from environment
yq -i '.database.password = env(DB_PASSWORD)' config.yaml

# Generate environment-specific configs
for env in dev staging prod; do
  yq ea 'select(fi == 0) * select(fi == 1)' base.yaml "env-${env}.yaml" > "config-${env}.yaml"
done

Mejores Prácticas

  • Siempre probar sin -iprimero: Ejecutar comandos sin la bandera de modificación en el lugar para previsualizar cambios antes de modificar archivos

    yq '.spec.replicas = 5' deployment.yaml  # Preview first
    yq -i '.spec.replicas = 5' deployment.yaml  # Then apply
    

  • Usar control de versiones: Confirmar archivos antes de modificaciones masivas para poder revertir fácilmente si es necesario

  • Entrecomillar expresiones: Usar comillas simples para expresiones para evitar la interpretación del shellbash yq '.items[] | select(.name == "test")' file.yaml # Correct- Validar YAML después de modificaciones: Asegúrate de que tus cambios produzcan un YAML válido

      yq '.' modified.yaml > /dev/null && echo "Valid YAML" || echo "Invalid YAML"
      ```- **Usar `select()`para actualizaciones condicionales**: Más preciso que actualizar todo
    ```bash
      yq '(select(.kind == "Deployment") | .spec.replicas) = 3' file.yaml
      ```- **Preservar comentarios**: yq preserva comentarios por defecto, pero ten cuidado con transformaciones complejas
    `eval-all`- **Usar ```bash
      yq ea '. as $item ireduce ({}; . * $item)' *.yaml
      ```para operaciones multi-archivo**: Más eficiente que procesar archivos por separado
    ```bash
      export SECRET_KEY="..."
      yq '.apiKey = env(SECRET_KEY)' config.yaml
      ```- **Aprovechar variables de entorno**: Mantener datos sensibles fuera de los scripts
    `-r`- **Usar salida raw para scripting**: Usar ```bash
      IMAGE=$(yq -r '.spec.template.spec.containers[0].image' deployment.yaml)
      ```flag al hacer pipe a otros comandos
    `-e`- **Verificar códigos de salida para validación**: Usar ```bash
      yq -e '.spec.replicas > 0' deployment.yaml && echo "Valid" || echo "Invalid"
      ```flag para fallar en resultados nulos/falsos
    
    | Problema | Solución |
    |-------|----------|
    | **Error: "bad file descriptor"** | Use `-i` flag correctly or redirect output: `yq '.' file.yaml > temp && mv temp file.yaml` |
    | **Changes not persisted** | Add `-i` flag for in-place editing: `yq -i '.field = "value"' file.yaml` |
    | **"null" appears in output** | Field doesn't exist or is null. Use alternative operator: `yq '.field // "default"' file.yaml` |
    | **Comments are removed** | Use `... comments=""` to explicitly remove, or check if using operations that don't preserve comments |
    | **Array merge replaces instead of concatenates** | Use `*+` instead of `*` for merge: `yq ea 'select(fi==0) *+ select(fi==1)' f1.yaml f2.yaml` |
    | **"Error: bad expression"** | Verificar la sintaxis de la expresión, asegurar que las comillas estén correctas, verificar que los operadores sean correctos |
    | **Output has extra quotes** | Use `-r` flag for raw output: `yq -r '.name' file.yaml` |
    | **Cannot process multiple files** | Use `ea` (eval-all) command: `yq ea '.' file1.yaml file2.yaml` |
    | **Wrong version of yq** | Verify you have mikefarah/yq (not kislyuk/yq): `yq --version` should show github.com/mikefarah/yq |
    | **Permission denied on `-i`** | Ensure write permissions: `chmod u+w file.yaml` or run with appropriate privileges |
    | **Encoding issues with special characters** | Ensure UTF-8 encoding: `yq --encoding=utf-8 '.' file.yaml` |
    | **Large files cause memory issues** | Process in chunks or use streaming: `yq -N '.items[]' large-file.yaml` |
    | **Path not found errors** | Verify path exists: `yq 'has("path.to.field")' file.yaml` before accessing |
    | **Merge conflicts with complex structures** | Use explicit merge strategies: `*d` for deep merge with deletion, `*+` for array concatenation |
    ## Resolución de problemas
    ```bash
    # Read value
    yq '.path.to.field' file.yaml
    
    # Update value
    yq -i '.path.to.field = "new-value"' file.yaml
    
    # Delete field
    yq -i 'del(.path.to.field)' file.yaml
    
    # Filter array
    yq '.items[] | select(.name == "target")' file.yaml
    
    # Merge files
    yq ea 'select(fi==0) * select(fi==1)' base.yaml override.yaml
    
    # Convert format
    yq -o=json '.' file.yaml
    
    # Use environment variable
    yq '.field = env(VAR_NAME)' file.yaml
    
    # Multiple operations
    yq -i '.field1 = "value1" | .field2 = "value2"' file.yaml