introducción a JQ con ejemplos

Hoy rescato un borrador que ha estado desde siempre en el blog. Básicamente quería empezar un post de introducción a jq que tuviera ejemplos prácticos, pues todo lo que he visto por ahí no me ha parecido muy práctico si estás empezando.

Lo primero, decir que jq pone a nuestra disposición una herramienta online para trastear con jq en jqplay.org, que nos puede venir bien.

Empezamos con el siguiente ejemplo:

❯ cat /tmp/jq-example
[
    {
        "nombre": "A",
        "reglas": [
            {
                "regla": "1",
                "posicion": "1"
            },
            {
                "regla": "2",
                "posicion": "2"
            }
        ]
    },
    {
        "nombre": "B",
        "reglas": [
            {
                "regla": "1",
                "posicion": "1"
            },
            {
                "regla": "3",
                "posicion": "3"
            }
        ]
    }
]

Podemos hacer referencia a los jsons del array, usando ‘.[]’, lo cual nos devolverá directamente el contenido del array

❯ jq '.[]' /tmp/jq-example
{
  "nombre": "A",
  "reglas": [
    {
      "regla": "1",
      "posicion": "1"
    },
    {
      "regla": "2",
      "posicion": "2"
    }
  ]
}
{
  "nombre": "B",
  "reglas": [
    {
      "regla": "1",
      "posicion": "1"
    },
    {
      "regla": "3",
      "posicion": "3"
    }
  ]
}

Y a sus elementos a partir de ahí. Por ejemplo, accederemos así a los valores de los diferentes elementos del array:

# Todos los campos "nombre"
❯ jq '.[].nombre' /tmp/jq-example
"A"
"B"

# Todos los campos "regla" ("reglas" es un array, por eso el "[]")
❯ jq '.[].reglas[].regla' /tmp/jq-example
"1"
"2"
"1"
"3"

# Todos los campos "regla" que estén en la segunda posición del array de "reglas"
❯ jq '.[].reglas[1].regla' /tmp/jq-example
"2"
"3"

Podemos usar la coma «,» para indicar varios campos a devolver

# Los campos "nombre" seguido de los campos "regla"
❯ jq '.[].nombre,.[].reglas[].regla' /tmp/jq-example
"A"
"B"
"1"
"2"
"1"
"3"

Pipes y selecciones

Puedo usar pipes para ir encadenando la salida de un filtro a la entrada de otro. Los que estáis familiarizados con Linux sabéis de lo que hablo.

Con «select», además, podemos seleccionar únicamente los objetos que hagan match con una determinada query

# Los objetos con "nombre == A"
❯ jq '.[] | select(.nombre=="A")' /tmp/jq-example
{
  "nombre": "A",
  "reglas": [
    {
      "regla": "1",
      "posicion": "1"
    },
    {
      "regla": "2",
      "posicion": "2"
    }
  ]
}

# El objeto que tengan una "regla == 3"
❯ jq '.[] | select(.reglas[].regla=="3")' /tmp/jq-example
{
  "nombre": "B",
  "reglas": [
    {
      "regla": "1",
      "posicion": "1"
    },
    {
      "regla": "3",
      "posicion": "3"
    }
  ]
}

Si un select hace match con más de un objeto, devolverá todos los objetos que hagan match.

Null

Podemos encontrarnos con por ejemplo, querer buscar por determinadas reglas, pero que uno de nuestros objetos no tenga ninguna regla. Si por ejemplo, al json original le añadimos el objeto «C» sin reglas.

❯ cat /tmp/jq-example
[
    {
        "nombre": "A",
        "reglas": [
            {
                "regla": "1",
                "posicion": "1"
            },
            {
                "regla": "2",
                "posicion": "2"
            }
        ]
    },
    {
        "nombre": "B",
        "reglas": [
            {
                "regla": "1",
                "posicion": "1"
            },
            {
                "regla": "3",
                "posicion": "3"
            }
        ]
    },
    {
        "nombre": "C"
    }
]

Cuando queramos iterar sobre las reglas, «C» nos devolverá «null» y según la query que estemos haciendo ésto nos devolverá a su vez un error

# Error de iteración
❯ jq '.[] | select(.reglas[].regla=="1")' /tmp/jq-example
jq: error (at :30): Cannot iterate over null (null)

Podemos jugar con las pipes para primero, descartar los objetos sin reglas, y posteriormente ya realizar la query:

# Primero eliminamos los elementos "null"
❯ jq '.[] | select(.reglas!=null) | select(.reglas[].regla=="1")' /tmp/jq-example
{
  "nombre": "A",
  "reglas": [
    {
      "regla": "1",
      "posicion": "1"
    },
    {
      "regla": "2",
      "posicion": "2"
    }
  ]
}
{
  "nombre": "B",
  "reglas": [
    {
      "regla": "1",
      "posicion": "1"
    },
    {
      "regla": "3",
      "posicion": "3"
    }
  ]
}

Y hasta aquí la introducción con ejemplos a jq.

A partir de aquí, documentación oficial:

https://stedolan.github.io/jq/manual/

Deja una respuesta

Tu dirección de correo electrónico no será publicada.