En muchos de mis posts, sobre todo cuando consultamos una API, uso una herramienta que se llama jq
. jq
nos permite mostrar y manipular datos en formato JSON
. Hay versiones para Windows, Linux y Mac. Yo lo uso en Fedora. Con este tutorial jq podrás filtrar datos, seleccionar solamente algunos campos o renombrarlos para luego mostrarlos.
Tutorial de jq
Instalar jq
Antes de iniciar con el tutorial de jq, vamos a instalar la herramienta en Fedora, ya que es el SO que yo estoy usando.
sudo dnf install jq
jq --version
jq-1.6
Archivo JSON
Yo voy a usar un archivo generado en esta herramienta, https://json-generator.com/. Lo he llamado generated.json
y lo dejo aquí para el ejemplo.
La estructura básica es una colección de elementos con esta estructura.
[
{
"id": "662c532532a9dbde2b724c4a",
"proveedor": "MARQET",
"nivel": 4,
"activo": false,
"contactos": [
{
"name": "Mann Sheppard",
"email": "[email protected]",
"phone": "+52 (808) 491-2250"
}
],
"facturas": [
{
"uuid": "3afdc82c-e759-4498-9798-a574445c6ae5",
"total": 2700.82,
"productos": [
{
"id": "662c53258b63d10e66f5e86e",
"producto": "velit magna"
},
]
}
]
}
]
Invocar jq
jq . generated.json
Cambiar la indentación
--indent n
: número de espacios.
jq . --indent 1 generated.json
Ordenar
--sort-keys
/ -S
: ordenar las keys en orden alfabético.
jq . -S generated.json
Seleccionar de un elemento por índice
En el ejemplo, el archivo no nos regresa directamente un elemento, sino que es unjq ‘.[0] | {proveedor, sus_facturas: [.facturas[] | {uuid, productos}]}’ generated.json array con varios elementos. Para seleccionar un elemento de acuerdo a su índice:
jq '.[0]' generated.json
0
es la posición que necesitas regresar. En caso de que no exista, jq
regresará null
.
Seleccionar un rango de elementos en un array
# Forma 1
jq '.[3:5]' generated.json
# Forma 2
jq '.[:2]' generated.json
En la “Forma 1” seleccionará desde el índice 3
hasta el 5
ya que excluye el segundo indicado o le resta 1.
En la “Forma 2” sería desde el 0
hasta el 2 - 1
.
Para los dos ejempos, la salida es de dos elementos.
Seleccionar campos
Campos como objeto
En nuestro archivo, hay muchos campos, y puede ser una pesadilla andar bajando poco a poco o hacer un less
y buscar lo que queremos.
Entonces podemos seleccionar solo los campos que necesitemos:
jq '.[] | {id, proveedor}' generated.json
# Salida
{
"id": "662c532532a9dbde2b724c4a",
"proveedor": "MARQET"
}
{
"id": "662c5325341074b0cf48a790",
"proveedor": "ZIDANT"
}
...
.[]
selecciona todos los elementos y luego con |
combinamos otro filtro. Después aplicamos {id, proveedor}
para decirle que me lo debe separar por objetos con solo esos campos.
Campos como lista de valores
Otra manera de hacerlo es:
jq '.[] | .proveedor' generated.json
# Salida
"MARQET"
"ZIDANT"
"EQUITAX"
"GEEKWAGON"
"MACRONAUT"
"DECRATEX"
"BIFLEX"
"COMDOM"
"ICOLOGY"
"EXOZENT"
De esta manera solo nos regresa los valores de los campos que coincidan con proveedor
.
Si queremos agregar campos y que los muestre en este formato, debemos separarlos por comas:
jq '.[] | .id, .proveedor' generated.json
# Salida
662c532532a9dbde2b724c4a"
"MARQET"
"662c5325341074b0cf48a790"
"ZIDANT"
"662c5325d4a0ca2d9939956f"
"EQUITAX"
"662c5325dd993c64c90afa5d"
...
Renombrar campos
jq '.[] | {ID: .id , NOMBRE: .proveedor}' generated.json
# Salida
{
"ID": "662c532532a9dbde2b724c4a",
"NOMBRE": "MARQET"
}
{
"ID": "662c5325341074b0cf48a790",
"NOMBRE": "ZIDANT"
}
...
Campos anidados
jq '.[0] | [.facturas[] | {ID: .uuid, productos}]' generated.json
Aquí seleccionamos el primer proveedor
, luego, con la propiedad facturas
renombramos el campo uuid
a ID
y también incluimos la propiedad productos
para cada una de las facturas.
jq '.[0] | {proveedor, sus_facturas: [.facturas[] | {uuid, total}]}' generated.json
Aquí seleccionamos el primer proveedor
, seleccionamos el campos proveedor
, renombramos el campo facturas
a sus_facturas
. Para cada una de las facturas seleccionamos el uuid
y el total
.
jq '.[0] | [.facturas[] | {id: .uuid, prods:[.productos[] | {producto} ]}]' generated.json
Aquí seleccionamos al primer proveedor
. Luego seleccionamos sus facturas
y para cada una de ellas, renombramos el uuid
a id
, incluimos los productos
, que renombramos a prods
, pero de los productos solo queremos el nombre
.
Operadores aritméticos
Es posible usar los operadores aritméticos como suma, resta, multiplicación o división.
Aquí vamos a dejar un ejemplo práctico:
jq '.[0] | [.facturas[] | {uuid, subtotal: .total, iva: (.total * 0.16), total: (.total * 1.16) }]' generated.json
Renombramos el total
a subtotal
y agregamos dos campos: iva
y total
.
Más en: https://jqlang.github.io/jq/manual/#builtin-operators-and-functions
Condicionales
if-else
Veamos un ejemplo usando la condicional if A then B else C end
y vamos a validar el total
de la factura. Si sobrepasa los 2000 entonces la marcaremos como válida, de lo contrario será inválida.
jq '.[0] | .facturas[] | { uuid, total, valida: (if .total > 2000 then true else false end) }' generated.json
NOTA: en la versión 1.7
es posible la forma if A then B end
.
and-or
Igual podemos hacer una doble validación junto con un if
.
jq '.[] | if .nivel > 3 and .activo == false then {id} else {nivel, activo} end ' generated.json
Colores
export JQ_COLORS="2;31:2;33:0;32:0;36:1;32:0;35:1;35:2;34"
- 1 (bright)
- 2 (dim)
- 4 (underscore)
- 5 (blink)
- 7 (reverse)
- 8 (hidden)
and the second is one of these:
- 30 (black)
- 31 (red)
- 32 (green)
- 33 (yellow)
- 34 (blue)
- 35 (magenta)
- 36 (cyan)
- 37 (white)
2;31 --> null
2;33 --> false
0;32 --> true
0;36 --> números
1;32 --> strings
0;35 --> arrays
1;35 --> objects
2;34 --> objects keys
Estas son las las opciones que más utilizo cuando uso esta herramienta. Tiene muchos más parámetros que pruedes aprovechar y puedes leer aquí.
Espero que este Tutorial de jq te sirva para el uso.
Gracias por leer.