Cuando implementas scripts en Bash, en ocasiones, mas frecuentemente de lo que puedas pensar, necesitas relacionarte con otras aplicaciones. Y no solo esto, sino que además descargas información de diferentes servicios web. En ocasiones está información viene en formato xml, o en texto plano, o en otros formatos, y en ocasiones viene en formato json
. ¿Como tratar con json en Bash?¿Como leer archivos json en Bash?¿Como procesar información json en Bash? Pues precisamente esto es lo que te quiero contar en este artículo, y en particular quiero centrarme en jq
.
Indicarte que dependendiendo de lo que quiera extraer, en muchas ocasiones, utilizo herramientas como awk, grep, sed o cut. Sin embargo, dependiendo de la complejidad de la información que quiera extraer de ese archivo, este proceso se puede convertir en algo realmente complejo. Así, es precisamente en estos casos, donde la complejidad del archivo a tratar es elevada, donde tener una herramienta como json
es garantía de éxito.
Tratar archivos json en Bash
jq
jq, tal y como lo define el desarrollador de la aplicación, es un ligero y flexible procesador de json para la línea de comandos.
Comparativamente es como sed
pero para el caso en el que tienes que tratar con archivos en formato json
. Esta herramienta, te permite trabajar con la misma sencillez y facilidad que lo harías con otras herramientas como, sed
, awk
o grep
.
Una interesante características de esta herramienta, es que está implementada en C
pero sin ninguna dependencia. De esta forma, tan solo tienes que descargar el archivo, copiarlo a la máquina donde lo necesites y comenzar a trabajar con el.
Filtrar texto
En resumen, jq
es un procesador de texto. Un procesador de texto que toma una entrada y produce una salida. Lo interesante de jq
es que viene preparado con un potente conjunto de filtros. Filtros que te ayudarán a extraer determinados campos, a convertir un número en texto, o a realizar otras tareas similares.
Para ver como trabajar con estos filtros, te propongo el siguiente archivo json
de ejemplo,
{
"colors": [
{
"color": "black",
"category": "hue",
"type": "primary",
"code": {
"rgba": [255,255,255,1],
"hex": "#000"
}
},
{
"color": "white",
"category": "value",
"code": {
"rgba": [0,0,0,1],
"hex": "#FFF"
}
}
]
}
Así, por ejemplo, si quisieras sacar el nombre del primer color, tan solo tienes que utilizar el filtro .colors[0].color
. Si quisieras sacar el código hexadecimal, el filtro sería colors[0].code.hex
. Sencillo, ¿no te parece?. Desde luego si estás familiarizado con las clases y los objetos esto es realmente sencillo para ti. En otro caso, simplemente tienes que pensar que con cada .
estás solicitando una propiedad del elemento superior… no se si con esto te habré aclarado mas las ideas o todo lo contrario.
Si quisieras obtener todos los colores, simplemente tienes que utilizar el mismo filtro que el caso anterior, pero sin indicar el índice, es decir colors[]
.
Ahora bien, si lo que quieres es un array con el valor color
de cada uno de los colores, el filtro que tienes que aplicar es .colors[].color
. Esto te devolverá lo siguiente,
"black"
"white"
Es posible aplicar varios filtros, de una sola vez pero dependiendo de lo que necesites tendrás que utilizar una solución u otra. Así,
,
utilizando la coma se aplicarán los diferentes filtros, pero de forma secuancial, y los resultados de cada uno de los filtros aplicados se concatenará al resultado final. Por ejemplo, el filtro
.colors[].code.hex,.colors[].color
devuelve,
"#000"
"#FFF"
"black"
"white"
|
con esta opcinón se aplican cada filtro al resultado de filtrar el anterior. Así por ejemplo, el filtro,
.colors[].code | .hex
devuelve
"#000"
"#FFF"
"#FF0"
Realizando operaciones
Es posible realizar operaciones matemáticas utilizando jq
. Así de vuelta al ejemplo que estás utilizando, es posible realizar la siguiente operación, por ejemplo,
.colors[].code.rgba[0]/2+5
Esto te devolverá,
132.5
5
Si quisieras que te devolviera un array, simplemente tienes que cerrar entre corchetes esa operación,
Funciones
Pero no solo esto, y es que resulta que jq
te ofrece diferentes funciones para trabajar con los archivos json
. Algunas de estas funciones son las siguientes,
length
te permite conocer el número de elementos de un array, o la longitud de una cadena de texto. Por ejemplo,.colors | length
te devolverá2
.keys
te devuelve las claves de un objeto. Por ejemplo,.colors[0] | keys
, te mostrará el siguiente resultado,
[
"category",
"code",
"color",
"type"
]
- la función
has
te permite comprobar si un determinado objeto tiene una clave concreta. Por ejemplo,.colors[0] | has("category")
te devolverátrue
. explode
convierte una cadena de texto en un array.implode
realiza la operación inversa a la anterior.map
para cada uno de los elementos de un array te devuelve el resultado de la operación.del
elimina una claveany
parte de un array y devolverátrue
si al menos uno de los elementos toma ese valor.all
hace lo mismo pero siempre que la condición la cumplan todos los elementos.flaten
parte de un array de arrays y lo convierte en un array simplerange
genera un rango de números.
No solo esto, sino que además jq
te proporcina operadores similares a SQL
. Eso si, no son muchos, se limita a unos pocos, como pueden ser JOIN
o IN
. Sin embargo, si te sientes cómodo utilizando este lenguaje, tienes aquí mas opciones.
Condicionales y comparadores
Puedes utilizar diferentes comparadores, así por ejemplo, puedes utilizar ==
, !=
. Así, en el ejemplo que estás utilizando, puedes probar lo siguiente,
$ jq '.colors[].category=="hue"' example.json
true
false
Otra opción interesante es utilizar if-then-else
. De nuevo si lo pruebas con el ejemplo que te traes entre manos,
jq 'if .colors[].category=="hue" then "buena" else "mala" end' example.json
"buena"
"mala"
No solo esto, sino que puedes utilizar otros operadores como and
, or
, not
. Incluso tienes la opción de utilizar try-catch
para capturar errores.
Y si todo esto te parece poco, también tienes la posibilidad de utilizar expresiones regulares. Simplemente las posibilidades que tienes son brutales. Por esto, te recomiendo que cuando tengas ocasión acudas a la documentación oficial de jq.
Probando jq
Indicarte, que puedes probar directamente el funcionamiento de jq
, sin necesidad de instalar nada. Simplemente abre jqplay, en un navegador y comienza a practicar con él. Pero por supuesto, también puedes probar esta herramienta directamente instalando la aplicación en tu equipo. Esto es algo tan sencillo como ejectuar sudo apt install jq
.
Más información,
Imagen de portada de Maarten van den Heuvel en Unsplash