Procesamiento de Datos JSON con jq

LinuxLinuxBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

¡Bienvenido al Laboratorio de Programación Linux jq! En este laboratorio, descubrirás cómo utilizar jq, un procesador JSON de línea de comandos ligero y versátil. Puedes pensar en jq como en sed, pero diseñado específicamente para datos JSON. Te permite dividir, filtrar, mapear y transformar datos estructurados sin esfuerzo. Este laboratorio está estructurado para guiarte desde el uso básico hasta el avanzado de jq a través de ejemplos prácticos que puedes aplicar en escenarios del mundo real, como procesar datos JSON de APIs o archivos de configuración.

Imagina que estás planeando un viaje a China y estás utilizando una aplicación de viajes que proporciona detalles sobre diversas atracciones, incluyendo sus ubicaciones, horas de apertura y reseñas. El backend de la aplicación almacena estos datos en formato JSON. Tu tarea es extraer piezas específicas de información para planificar tu viaje de manera efectiva. Este laboratorio demostrará cómo utilizar jq para consultar y manipular estos datos JSON, lo que te permitirá identificar rápidamente las atracciones perfectas para visitar.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) linux(("Linux")) -.-> linux/InputandOutputRedirectionGroup(["Input and Output Redirection"]) linux/BasicFileOperationsGroup -.-> linux/cat("File Concatenating") linux/InputandOutputRedirectionGroup -.-> linux/pipeline("Data Piping") subgraph Lab Skills linux/cat -.-> lab-279945{{"Procesamiento de Datos JSON con jq"}} linux/pipeline -.-> lab-279945{{"Procesamiento de Datos JSON con jq"}} end

Consultas JSON Básicas

Comencemos aprendiendo cómo extraer datos simples de un objeto JSON.

Ahora deberías tener el archivo data.txt en tu directorio /home/labex/project/. Contiene datos JSON que representan una lista de atracciones. El contenido del archivo se ve así:

[
  {
    "name": "The Great Wall of China",
    "location": "Shanxi Province",
    "opening_hours": "24 hours"
  },
  {
    "name": "Terracotta Warriors",
    "location": "XiAn",
    "opening_hours": "9:00 AM -  5:00 PM"
  }
]

Nuestro objetivo aquí es extraer los nombres de todas las atracciones enumeradas en estos datos JSON.

Para lograr esto, utiliza el siguiente comando:

cat ~/project/data.txt | jq '.[] |.name'

Este comando producirá la siguiente salida:

"The Great Wall of China"
"Terracotta Warriors"

Analicemos lo que está sucediendo en este comando. cat ~/project/data.txt simplemente lee el contenido del archivo data.txt. El símbolo |, conocido como tubería (pipe), toma la salida del comando cat y la alimenta como entrada al comando jq. El núcleo de la lógica de extracción está en jq '.[] |.name'. Así es como jq procesa esto:

  • .[] le dice a jq que itere a través de cada elemento (en este caso, cada objeto de atracción) en la matriz JSON.
  • | nuevamente, canaliza el resultado de la iteración a la siguiente operación, en este caso .name.
  • .name extrae el valor asociado con la clave "name" de cada uno de los objetos de atracción.

En esencia, el comando recorre cada atracción, selecciona su nombre y lo muestra.

Filtrado de Datos JSON

Pasemos al filtrado de datos JSON basado en criterios específicos.

Nuestro objetivo es encontrar solo aquellas atracciones que estén abiertas las 24 horas.

Utiliza el siguiente comando para lograr esto:

cat ~/project/data.txt | jq '.[] | select(.opening_hours == "24 hours") |.name'

Al ejecutar este comando, se mostrará lo siguiente:

"The Great Wall of China"

Así es cómo funciona el filtrado: El comando comienza con cat ~/project/data.txt | jq '.[]', que, como antes, lee el archivo y itera sobre cada atracción. La parte clave es la adición de select(.opening_hours == "24 hours"):

  • select() es una función de jq que te permite filtrar elementos del JSON basado en una condición que especifiques.
  • La condición .opening_hours == "24 hours" verifica si el valor del campo opening_hours es exactamente igual a la cadena "24 hours". Solo las atracciones que cumplan con esta condición se pasarán a la siguiente etapa.
  • La última parte, |.name, simplemente extrae el nombre de cada atracción que pasó el filtro.

En este caso, solo "The Great Wall of China" cumple con la condición, por lo que es el único nombre que se extrae y muestra.

Transformación de Datos JSON

Ahora, exploremos cómo transformar datos JSON en un formato diferente y más útil.

Nuestro objetivo aquí es hacer que las horas de apertura sean más legibles. Específicamente, si una atracción está abierta las 24 horas, queremos mostrar "Open 24 hours"; de lo contrario, agregaremos el prefijo "Open " al texto de las horas de apertura existente.

Utiliza el siguiente comando para lograr esto:

cat ~/project/data.txt | jq '.[] | {name:.name, location:.location, opening_hours: (.opening_hours | if. == "24 hours" then "Open 24 hours" else "Open \(.)) end)}'

Este comando produce la siguiente salida:

{
  "name": "The Great Wall of China",
  "location": "Shanxi Province",
  "opening_hours": "Open 24 hours"
}
{
  "name": "Terracotta Warriors",
  "location": "XiAn",
  "opening_hours": "Open 9:00 AM -  5:00 PM"
}

Comprendamos la transformación: Como antes, cat ~/project/data.txt | jq '.[]' nos permite comenzar leyendo el archivo e iterando a través de cada atracción en la matriz. El núcleo de esta transformación está en la construcción del objeto y la declaración if-else:

  • {name:.name, location:.location, opening_hours:...} crea un nuevo objeto JSON, extrayendo datos del objeto original. Incluye directamente el name y location del objeto original. Sin embargo, el valor del campo opening_hours es más complejo.
  • (.opening_hours | if. == "24 hours" then "Open 24 hours" else "Open \(.)) end) toma el valor de las horas de apertura originales y lo procesa:
    • .opening_hours selecciona el valor original de las horas de apertura.
    • La declaración if. == "24 hours" then "Open 24 hours" else "Open \(.)) end verifica si las horas de apertura originales son exactamente iguales a "24 hours". Si lo son, el valor se reemplaza con "Open 24 hours". Si no, se agrega "Open " como prefijo a las horas de apertura existentes. Nótese el uso de \(.)), que nos permite incrustar el valor dentro de la cadena.

En esencia, este comando transforma los datos creando un nuevo objeto para cada atracción y ajustando el valor de opening_hours para que sea más legible para el usuario.

Resumen

¡Felicidades! Has completado con éxito el Laboratorio de Programación Linux jq. Has aprendido cómo consultar, filtrar y transformar datos JSON utilizando jq, una herramienta poderosa para trabajar con datos estructurados directamente desde la línea de comandos. Ya sea que estés procesando datos de APIs, archivos de configuración o cualquier otra fuente JSON, jq te permite extraer, filtrar y manipular los datos que necesitas con gran eficiencia y claridad.

Recuerda, la práctica constante es esencial para dominar jq y otras herramientas de línea de comandos. No dudes en experimentar con tus propios datos JSON, probando diferentes consultas y transformaciones. ¡Que disfrutes codificando!