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’` |
yq -r '.name' file.yaml | Salida de cadena sin procesar (sin comillas) |
| `yq ‘.items \ | length’ file.yaml` |
yq 'keys' file.yaml | Enumerar todas las claves de nivel superior |
| `yq ’.[] \ | keys’ file.yaml` |
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` |
| `yq ‘.items[] \ | select(.kind == “Pod” and .status == “Running”)’ file.yaml` |
| `yq ‘.items[] \ | select(.kind == “Pod” or .kind == “Service”)’ file.yaml` |
| `yq ‘.items[] \ | seleccionar(.nombre \ |
| `yq ‘.items[] \ | select(has(“metadata”))’ file.yaml` |
| `yq ‘.items[] \ | select(.replicas > 3)’ file.yaml` |
| `yq ‘.items[] \ | seleccionar(.etiquetas \ |
| `yq ‘.items[] \ | select(.name != null)’ file.yaml` |
| `yq ’.[] \ | select(tag == “!!str”)’ file.yaml` |
Uso Avanzado - Operaciones con Arreglos
| Comando | Descripción |
|---|
| `yq ‘.items \ | = sort_by(.name)’ file.yaml` |
| `yq ‘.items \ | = sort_by(.metadata.creationTimestamp)’ file.yaml` |
| `yq ‘.items \ | = reverse’ file.yaml` |
| `yq ‘.tags \ | unique’ file.yaml` |
| `yq ‘.items \ | flatten’ file.yaml` |
| `yq ‘.items \ | group_by(.kind)’ file.yaml` |
| `yq ‘.items \ | map(.name)’ file.yaml` |
| `yq ‘.items \ | map(select(.active))’ file.yaml` |
yq '.items = .items + .newItems' file.yaml | Concatenar arrays |
| `yq ‘.items \ | = unique_by(.name)’ file.yaml` |
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` |
| `yq ‘.name \ | = downcase’ file.yaml` |
| `yq ‘.name \ | = trim’ file.yaml` |
| `yq ‘.text \ | = sub(“old”, “new”)’ file.yaml` |
| `yq ‘.text \ | = gsub(“old”, “new”)’ file.yaml` |
| `yq ‘.path \ | split(”/”)’ file.yaml` |
| `yq ‘.tags \ | join(”, ”)’ file.yaml` |
| `yq ‘.name \ | length’ file.yaml` |
| `yq ‘.text \ | contains(“substring”)’ file.yaml` |
| 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
# 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 shell```bash
yq ‘.items[] | select(.name == “test”)’ file.yaml # Correct
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