Comandos LinuxExplicados en español
/
Ficha33 / 104
Categoría
Texto
Ejemplos
6
Ver también
curl · grep · tee · sort

jq

jq (se pronuncia 'jay cue'; procesador de JSON para la terminal)

Filtra, ordena y da formato a datos JSON desde la terminal.

Toma un JSON y te devuelve la parte que le pidas: un campo, una lista ya filtrada, un valor por renglón. Lo usas cuando un comando entrega JSON, como las APIs que consultas con curl, y quieres leerlo rápido, buscar algo en particular o pasarlo limpio a otro programa. En Debian 13 / Ubuntu 24.04 no viene instalado por defecto: sudo apt install jq.

Sintaxisjq [opciones] FILTRO [archivo...]
§ 1

Despiece

6 ejemplos
Ver un JSON bien formateado

Ver un JSON bien formateado

3 piezas
Lámina01 / 06
Comandojq . datos.json
Piezas3
Escala1:1
N.ºPiezaTipoQué hace
1jqComandoEl procesador de JSON.
2.ValorEl filtro. El punto solo significa 'pasa el dato tal cual', pero al imprimirlo jq lo deja indentado y legible.
3datos.jsonArgumentoEl archivo de entrada; también puedes escribir el JSON entre comillas o ponerlo en un pipe.
Resultado

jq sin filtro devuelve lo mismo que le diste, pero con formato: una clave por renglón y sangría. Sirve para leer de un vistazo un JSON que venía todo pegado, por ejemplo la respuesta de curl.

Sacar un solo valor

4 piezas
Lámina02 / 06
Comandojq -r '.servidor' config.json
Piezas4
Escala1:1
N.ºPiezaTipoQué hace
1jqComandoEl procesador de JSON.
2-rOpciónRaw output: imprime el texto sin las comillas que jq pondría para que la salida siga siendo JSON válido.
3'.servidor'ValorEl filtro. El punto accede a la clave servidor; las comillas protegen el texto de la terminal.
4config.jsonArgumentoEl archivo de donde sale el valor.
Resultado

Imprime web-01, limpio y sin comillas gracias a la -r. Sin esa opción verías "web-01", y eso es lo que terminaría guardado si lo mandas a un archivo para que otro programa lo lea.

Sacar un campo de una lista

4 piezas
Lámina03 / 06
Comandojq -r '.usuarios[] | .email' datos.json
Piezas4
Escala1:1
N.ºPiezaTipoQué hace
1jqComandoEl procesador de JSON.
2-rOpciónImprime los textos sin comillas.
3'.usuarios[] | .email'ValorEl filtro: los corchetes [] recorren el arreglo usuarios y la barra | encadena un filtro sobre el resultado del anterior. Dentro de las comillas, la barra no la toma la terminal.
4datos.jsonArgumentoEl archivo con el arreglo.
Resultado

Una línea por usuario, con su correo. El | es el mismo pipe de la terminal, pero dentro de las comillas jq lo usa como encadenador: primero recorre el arreglo y luego a cada elemento le pide su email.

Filtrar los que cumplen una condición

4 piezas
Lámina04 / 06
Comandojq -r '.[] | select(.edad > 30) | .nombre' equipo.json
Piezas4
Escala1:1
N.ºPiezaTipoQué hace
1jqComandoEl procesador de JSON.
2-rOpciónImprime los textos sin comillas.
3'.[] | select(.edad > 30) | .nombre'ValorEl filtro: recorre el arreglo, select() deja pasar solo lo que cumple la condición y al final se extrae el nombre.
4equipo.jsonArgumentoEl archivo con el arreglo de personas.
Resultado

Imprime solo los nombres de quienes tienen más de 30 años. select() funciona como un WHERE de SQL: deja pasar los elementos que cumplen la condición. Puedes encadenar varios: '.[] | select(.edad > 30) | select(.ciudad == "CDMX") | .nombre'.

Pasar un JSON a CSV

4 piezas
Lámina05 / 06
Comandojq -r '.[] | [.id, .nombre] | @csv' datos.json
Piezas4
Escala1:1
N.ºPiezaTipoQué hace
1jqComandoEl procesador de JSON.
2-rOpciónImplica comillas dobles reales en vez de los caracteres escapados que JSON usaría.
3'.[] | [.id, .nombre] | @csv'ValorEl filtro: los corchetes [] arma un arreglo nuevo con los dos campos, y @csv lo convierte en una línea separada por comas.
4datos.jsonArgumentoEl archivo de entrada.
Resultado

Cada elemento sale como una línea CSV: 1,"Ana" y 2,"Luis". Es el puente para abrir el resultado en Excel o Calc, o para cargarlo en una base de datos. Quita el -r y verás las comillas dobles escapadas, inútiles para una hoja de cálculo.

Modificar un valor y guardar el resultado

5 piezas
Lámina06 / 06
Comandojq '.puerto = 8081' config.json > config.nuevo.json
Piezas5
Escala1:1
N.ºPiezaTipoQué hace
1jqComandoEl procesador de JSON.
2'.puerto = 8081'ValorEl filtro: una asignación. Busca la clave puerto y le pone 8081, dejando todo lo demás igual.
3config.jsonArgumentoEl archivo de entrada, que no se modifica.
4>OperadorLa redirección: manda la salida de jq al archivo nuevo.
5config.nuevo.jsonArgumentoEl archivo donde queda el JSON ya cambiado.
Resultado

config.nuevo.json queda con puerto 8081 y todo lo demás intacto. jq nunca modifica el archivo de entrada: escribe el JSON transformado en la salida, y por eso el > va de salida. Con tee en vez de > también verías el cambio en pantalla.

§ 2

Opciones

Las que sí vas a usar
OpciónQué hace
-r--raw-outputImprime los textos sin las comillas de JSON. Sin esto, un valor de texto sale como "web-01", con comillas.
-c--compact-outputSaca todo en una sola línea, sin saltos ni sangrías. Es el que se usa en scripts y para meter el JSON en la línea de otro comando.
-e--exit-statusDevuelve código de salida 1 cuando el filtro no arroja nada (null, false o no encuentra el campo) y 0 cuando sí. Sirve para decidir en un script sin comparar texto.
-n--null-inputNo lee ningún archivo: usa null como valor de entrada. Junto con un filtro que arma el JSON, sirve para crear archivos desde cero.
-s--slurpLee todos los archivos de entrada y los junta en un solo arreglo, en vez de procesar cada uno por separado.
-S--sort-keysOrdena las claves alfabéticamente al imprimir. Útil para comparar dos JSON y ver de un vistazo qué cambió.
-R--raw-inputCada línea se lee como texto plano, sin intentar entenderla como JSON. Para trabajar con archivos que no son JSON.
--indent nCambia la sangría del formato: por omisión son dos espacios, con --indent 4 quedan cuatro y con --tab se usan tabulaciones.
§ 3

Fallas comunes

FallaRemedio
Olvidar la -r y guardar el valor con comillas.jq devuelve JSON válido, así que un texto sale entre comillas. Cuando vas a usar el valor en otro comando o guardarlo en un archivo para otro programa, casi siempre necesitas -r.
Escribir el filtro mal y que jq se queje de sintaxis o te devuelva null.Un objeto se abre con .clave y un arreglo con .[]; los corchetes son para índices y las llaves son para construir objetos. Si olvidas las comillas, la terminal se come los | y corta el comando por ahí, porque en ese punto el pipe ya no lo maneja jq.
Meterle un archivo que no es JSON y no entender el error.jq responde parse error e incluso te dice la línea donde falló. Para trabajar con texto plano usa -R, que lee cada línea como texto sin interpretarla: jq -R -r '.' notas.txt. Y si el archivo trae texto antes del JSON, quítalo primero con tail.
Redirigir la salida al mismo archivo de entrada y quedarse con el JSON vacío.jq -r '.puerto = 8081' config.json > config.json vacía el archivo antes de que jq lo lea, y el resultado es un archivo de cero bytes. Siempre a otro nombre: > config.nuevo.json. Si de verdad necesitas reemplazar el original, pásalo por sponge: jq ... config.json | sponge config.json, que viene en el paquete moreutils.
§ 4

Preguntas frecuentes

¿Para qué sirve jq si cat ya me muestra el archivo?
cat te escupe el JSON crudo, tal como viene: en una sola línea o con las claves pegadas. jq lo da formateado con sangrías y, sobre todo, te deja pedir solo la parte que te interesa, como .servidor o una lista filtrada por una condición. También sirve para convertir a CSV o para editar valores antes de guardar.
¿Cómo saco un campo de un JSON?
Con el filtro del punto seguido del nombre de la clave: jq -r '.servidor' config.json. Si el campo está anidado, encadena puntos o usa corchetes: .red.local.puerto. Para un arreglo, los corchetes vacíos lo recorren: .usuarios[] | .email. La -r es casi siempre obligatoria si quieres texto limpio.
¿Cuál es la diferencia entre jq '.a' y jq -r '.a'?
El filtro es el mismo; cambia cómo se imprime. Sin -r, jq devuelve JSON válido: los textos salen entre comillas y con los saltos de línea escapados. Con -r imprime el valor tal cual, que es lo que quieres cuando lo usas en otro comando o en un archivo.
¿Cómo convierto un JSON a CSV o a una línea por registro?
Con @csv al final del filtro: jq -r '.[] | [.id, .nombre] | @csv' datos.json. Los corchetes arman el arreglo con las columnas en el orden que quieres y @csv lo convierte en texto separado por comas. Si solo quieres un valor por línea, ya lo hace el filtro solo: jq -r '.usuarios[].email' datos.json.
¿Cómo creo un archivo JSON desde cero con jq?
Con la opción -n, que le dice que no espere ninguna entrada, y un filtro con llaves: jq -n '{"nombre": "Ana", "edad": 31}' > datos.json. Las llaves construyen el objeto y las comillas impiden que la terminal las toque. También sirve para pasar variables del shell con --arg o --argjson: jq -n --arg nombre "$NOMBRE" '{nombre: $nombre}'.
§ 5

Ver también