¿Cuántas veces has hecho una petición a una API, has recibido una pared de JSON sin formato y has pensado "aquí tiene que haber una forma mejor"? Hoy en día prácticamente todo devuelve JSON: las APIs de servicios web, las configuraciones de herramientas modernas, los resultados de las búsquedas de tus propios scripts. Pero leer un JSON de dos mil líneas a simple vista es un castigo, y extraer un solo campo con grep es frágil y acaba rompiéndose.

Existe una herramienta pensada exactamente para eso: jq. Es un procesador de JSON de línea de comandos, ligero, gratuito y de código abierto, que se ha convertido en el estándar de facto para trabajar con datos estructurados desde la terminal. Si usas APIs, automatizas tareas o simplemente quieres entender qué contiene un archivo de configuración sin abrir un editor, jq te va a ahorrar horas.

En este tutorial vas a aprender desde lo más básico —leer y formatear un JSON— hasta trucos de nivel intermedio como filtrar listas, renombrar campos y construir nuevas estructuras. Todo con ejemplos reales que puedes probar en tu terminal en cinco minutos.


¿Qué es jq y por qué lo necesitas?

jq es un programa escrito en C que funciona como un filtro: recibe JSON por la entrada, aplica una serie de operaciones que tú defines y devuelve el resultado por la salida. Se usa igual que grep o sed, pero pensado específicamente para datos estructurados.

La gran ventaja frente a los trucos de texto es que jq entiende la estructura del JSON, no solo las cadenas. Sabe distinguir entre objetos, arrays, números, booleanos y cadenas, y puede recorrer esa estructura con una sintaxis parecida a JavaScript. Esto hace que las operaciones sean mucho más fiables: no dependes de que el formato de los espacios coincida, porque jq parsea el documento de verdad.

Algunos usos cotidianos:

  • Formatear una respuesta de API para poder leerla.
  • Extraer campos concretos de un listado de resultados.
  • Filtrar elementos que cumplen una condición (por ejemplo, todos los posts de una categoría).
  • Contar, sumar y agrupar valores para hacer mini-análisis sin abrir una hoja de cálculo.
  • Convertir entre formatos o construir el JSON de entrada para otra herramienta.

Es una de esas herramientas que, una vez que la conoces, no entiendes cómo trabajabas antes sin ella.


Instalación: en menos de un minuto

La instalación es trivial en cualquier sistema. En Linux, la mayoría de distribuciones lo incluyen en sus repositorios oficiales:

ice-tech
# Debian / Ubuntu / derivados
sudo apt install jq

# Fedora
sudo dnf install jq

# Arch Linux
sudo pacman -S jq

En macOS, si usas Homebrew, es igual de sencillo:

ice-tech
brew install jq

Y en Windows tienes varias opciones: el gestor winget de Windows 11 (winget install jq), choco (choco install jq), o descargar el ejecutable independiente desde la página del proyecto en GitHub y añadirlo al PATH.

Para comprobar que todo funciona, ejecuta:

ice-tech
$ echo '{"saludo": "hola"}' | jq .

{
  "saludo": "hola"
}

El . es el filtro más básico de jq: significa "pásame el documento completo tal cual". Y aquí ya ves la primera magia: jq formatea automáticamente el JSON con indentación y colores. Ese simple comportamiento ya convierte a jq en el mejor "formateador de JSON" que puedes tener en tu máquina.


Los fundamentos: filtros, pipes y notación de puntos

La sintaxis de jq se basa en filtros. Un filtro recibe un valor y produce otro. Puedes encadenar filtros con el carácter | (pipe), igual que en la terminal de Linux.

Acceder a campos de un objeto

Dado un objeto JSON, accedes a sus propiedades con un punto:

ice-tech
echo '{"nombre": "Ana", "edad": 32}' | jq .nombre

Esto imprime "Ana". Fíjate en un detalle importante: jq devuelve el valor con su tipo, así que las cadenas salen entre comillas. Si quieres el valor sin comillas —por ejemplo para meterlo en un script— usas la opción -r (raw output):

ice-tech
echo '{"nombre": "Ana", "edad": 32}' | jq -r .nombre

Esto imprime Ana a secas, perfecto para asignarlo a una variable de bash o pasárselo a otro comando.

Navegar por estructuras anidadas

Los objetos anidados se recorren encadenando puntos:

ice-tech
echo '{"usuario": {"perfil": {"nombre": "Ana"}}}' | jq .usuario.perfil.nombre

Si hay arrays de por medio, usas corchetes con el índice:

ice-tech
echo '{"posts": ["uno", "dos", "tres"]}' | jq .posts[1]

Recuerda que los índices empiezan en cero, así que [1] devuelve "dos".

Trabajar con arrays completos

Una de las operaciones más útiles es .[], que itera sobre los elementos de un array. La diferencia es sutil pero importante: .posts devuelve el array entero, mientras que .posts[] devuelve cada elemento por separado, en líneas distintas.

ice-tech
echo '{"posts": ["uno", "dos", "tres"]}' | jq .posts[]
ice-tech
"uno"
"dos"
"tres"

Esto es la base de casi todo lo que viene después: iterar sobre una lista y extraer un campo de cada elemento.


Ejemplo real: extraer datos de una API

Pongamos un caso práctico. Imagina que quieres saber qué repositorios están en tendencia hoy en la API de GitHub. La respuesta es un array de objetos con decenas de campos: nombre, autor, estrellas, descripción, lenguaje, etc. Con jq puedes extraer solo lo que te interesa:

ice-tech
curl -s "https://api.github.com/search/repositories?q=language:python&sort=stars&per_page=5" \
  | jq '.items[] | {nombre: .full_name, estrellas: .stargazers_count, lenguaje: .language}'

Vamos por partes: .items[] itera sobre los repositorios que devuelve la API, y el bloque {...} construye un nuevo objeto por cada uno, con los campos que hemos elegido y renombrados a nuestro gusto. El resultado es una lista limpia y legible en lugar de la maraña original.

Esta combinación —curl + jq— es probablemente el uso más habitual de la herramienta. Cualquier API moderna (GitHub, OpenWeather, la que use tu servicio favorito) se convierte en una fuente de datos manejable desde la terminal, sin necesidad de abrir Postman ni escribir un script de Python.


Filtrar con select: quédate solo con lo que importa

El filtro select() es el equivalente de jq a un WHERE de SQL. Devuelve solo los elementos que cumplen una condición. Por ejemplo, imagina un JSON con una lista de artículos y quieres los de la categoría "Tutorial":

ice-tech
cat articulos.json | jq '.[] | select(.categoria == "Tutorial") | .titulo'

Aquí hay tres partes: iterar sobre el array (.[]), quedarse con los que cumplen la condición (select(...)), y extraer el título. Puedes combinar condiciones con and / or, y comparar números sin problema:

ice-tech
jq '.[] | select(.estrellas > 1000 and .lenguaje == "python") | .nombre'

Otra operación muy práctica es map(), que aplica una transformación a todos los elementos de un array. Por ejemplo, para quedarte con una lista de nombres a partir de un array de objetos:

ice-tech
jq 'map(.nombre)'

select y map juntos te permiten hacer el 90 % del "análisis de datos" que la gente hace abriendo Excel, pero desde una línea de comandos y sin salir de tu flujo de trabajo.


Contar, sumar y ordenar: mini-estadísticas con jq

jq no es una herramienta de análisis pesado, pero para operaciones rápidas va sobrado. Tres ejemplos clásicos:

Contar cuántos elementos hay:

ice-tech
cat posts.json | jq 'length'

Sumar un campo numérico de todos los elementos:

ice-tech
cat repos.json | jq '[.[].estrellas] | add'

Fíjate en los corchetes: envuelven el resultado de iterar en un array nuevo, y add suma todos sus elementos. Este patrón —[.[].campo]— es la forma estándar de "recoger todos los valores de un campo en una lista".

Ordenar por un campo:

ice-tech
cat repos.json | jq 'sort_by(.estrellas) | reverse | .[0:3]'

Esto ordena los repositorios por estrellas, invierte el orden (de mayor a menor) y se queda con los tres primeros. El slicing .[0:3] funciona igual que en Python.


Trucos de nivel intermedio

Cuando domines lo básico, estos trucos te van a sacar de más de un apuro:

Quitar las comillas de los valores ya lo vimos con -r, pero también puedes usarlo en medio de un pipeline para construir salidas tipo CSV:

ice-tech
cat articulos.json | jq -r '.[] | [.titulo, .categoria, .fecha] | @csv'

@csv convierte el array en una línea de CSV con las comas y comillas correctas. Útil para volcar datos a una hoja de cálculo.

Comprobar si un JSON es válido sin tener que mirarlo: si jq procesa el documento sin error, es válido. Un truco rápido:

ice-tech
echo '{"roto": true' | jq . > /dev/null && echo "JSON válido" || echo "JSON inválido"

Actualizar un valor en un archivo con map_values o asignación directa:

ice-tech
jq '.version = "2.0"' config.json > config_nuevo.json

Esto devuelve el documento completo con el campo version cambiado. Ojo: jq no modifica archivos in-place, así que rediriges la salida a un archivo nuevo y luego lo mueves.

El modo compacto con -c te da el JSON en una sola línea, muy útil cuando quieres procesar línea a línea con otros comandos o guardar logs:

ice-tech
curl -s https://api.github.com/zen | jq -c .

Errores comunes y cómo evitarlos

Los fallos más frecuentes con jq tienen una causa común: confundir cuándo estás iterando y cuándo no.

  • Cannot iterate over null: intentaste hacer .[] sobre algo que no es un array (por ejemplo, la API devolvió un objeto de error). Solución: inspecciona primero con jq . para ver qué devuelve realmente la petición.
  • Olvidar las comillas: en bash, el filtro de jq va siempre entre comillas simples. Si lo escribes sin comillas, bash interpreta los caracteres especiales (. se expande, [ es un glob) y jq recibe un filtro destrozado.
  • Valores con comillas en la salida: si ves "Ana" y esperabas Ana, te falta -r para la salida en crudo.
  • Querer modificar el archivo original: jq nunca toca el archivo de entrada. Usa redirección a un archivo temporal y luego mv.

jq en tu día a día: tres ideas para empezar

Para terminar, tres usos prácticos que puedes incorporar desde hoy:

  1. Explorar respuestas de API: cada vez que hagas un curl a una API, añade | jq . al final. Ya no volverás a leer JSON pegado.
  2. Auditar configuraciones: muchos archivos de configuración modernos son JSON (o JSONC). Un jq . rápido te dice de un vistazo si están bien formados y qué contienen.
  3. Scripts de automatización: combina jq con curl en tus scripts de bash para extraer datos de servicios web sin depender de librerías. Un par de líneas de bash + jq pueden sustituir a un script de Python entero cuando solo necesitas "coger este campo y aquel otro".

jq tiene una curva de aprendizaje suave: con los filtros de este artículo ya cubres el 95 % de los casos reales. El resto —funciones propias, recursión, operaciones con fechas— lo irás descubriendo cuando lo necesites. La documentación oficial en la web del proyecto es excelente y tiene un manual interactivo que te permite probar los ejemplos directamente en el navegador.

La próxima vez que una API te devuelva un JSON ilegible, ya sabes qué hacer: respira, escribe | jq . y deja que la terminal haga el trabajo sucio.