Extraer la clave y los contenidos de nivel superior de un JSON grande utilizando streaming
Un procedimiento en un sistema consiste en ‘extraer’ una clave y su valor (objeto) a un archivo dedicado para posteriormente procesarlo de alguna manera en un script (irrelevante).
Un subconjunto representativo del archivo JSON original se ve así:
{
"version": null,
"produced": "2021-01-01T00:00:00+0000",
"other": "contenido aquí",
"items": [
{
"code": "AA",
"name": "Ejemplo 1",
"prices": ["otro", "contenido", "aquí"]
},
{
"code": "BB",
"name": "Ejemplo 2",
"prices": ["otro", "contenido", "aquí"]
}
]
}
Y la salida actual, dada esa subconjunto como entrada, simplemente es igual a:
[
{
"code": "AA",
"name": "Ejemplo 1",
"prices": ["otro", "contenido", "aquí"],
},
{
"code": "BB",
"name": "Ejemplo 2",
"prices": ["otro", "contenido", "aquí"],
},
...
]
Anteriormente, extraíamos toda la sección de “items” utilizando jq
con un comando muy sencillo (que funcionaba bien):
cat file.json | jq '.items' > file.items.json
Sin embargo, recientemente el tamaño del archivo JSON original ha aumentado drásticamente, lo que provoca que el script falle debido a un error de “Sin memoria”. Una solución obvia es usar la opción ‘stream’ de jq. Sin embargo, estoy un poco atascado en cómo convertir el comando anterior en un filtro válido en la sintaxis de ‘stream’ de jq.
cat file.json | jq --stream '...' > file.items.json
Cualquier consejo sobre qué usar como filtro para este comando sería muy apreciado. ¡Gracias de antemano!
davy.ai
Para extraer la clave “items” y su valor correspondiente utilizando la opción
--stream
en jq, se puede utilizar el siguiente filtro:Este filtro primero selecciona solo aquellos arrays en el flujo que tengan una longitud de 2 y cuyo último valor del primer elemento sea “items”. Luego, solo se imprime el segundo elemento de ese array en el archivo “file.items.json”. Esto extraerá solo la clave “items” y sus valores del archivo JSON original sin agotar los recursos de memoria.