Automatizando la extracción de datos de un gran archivo JSON (~8GB)
Tengo un archivo JSON bastante grande (~8GB) que tiene el siguiente formato:
{
// algunos campos fijos
"data": [
{
// campos no importantes
"importantField": "una cadena alfanumérica"
},
{
// mismo formato que el anterior
},
...
]
}
Quiero extraer todos los valores del campo importantField
en un archivo separado y quiero hacerlo automáticamente.
Intenté usar este comando grep
:
grep -E -o '"importantField":"[[:alnum:]]+"' file.json
pero el proceso se detuvo debido al uso de memoria grande (usó más del 80% de mi RAM en algunos puntos y la interfaz gráfica no respondía).
Luego intenté primero usar el comando split
para separar la entrada en archivos de 2GB:
split --bytes 2000000000 file.json out_
y luego usar el mismo comando grep
de arriba, y esta vez terminó rápidamente para cada fragmento, en unos 30 segundos.
Este método en el que tengo que dividir primero la entrada estaría bien para mí, pero el único problema es verificar automáticamente si el comando split
divide correctamente el archivo, es decir, no en medio del par clave-valor de importantField
, ya que eso resultaría en la pérdida de datos importantes.
Me gustaría saber si hay una forma mejor/más elegante de hacer esto.
También me interesa saber por qué el comando grep
no funciona en un archivo de 8GB, pero funciona perfectamente en archivos de 2GB. La expresión regular que uso para hacer la coincidencia no parece ser mala.
Mi suposición es que intenta cargar toda la línea primero (lo cual utiliza la mitad de mi RAM) y luego usa más memoria para sus cálculos internos, lo que hace que el sistema comience a usar la memoria SWAP, lo que a su vez provoca un rendimiento realmente lento antes de terminar el programa (10+ minutos).
Algunos datos importantes específicos para este problema:
– El formato de los objetos dentro del array data
siempre será el mismo.
– El archivo JSON de entrada está minificado, no contiene espacios ni nuevas líneas.
– El archivo de entrada es estático.
– Obviamente, estoy interesado en extraer todos los datos importantes.
davy.ai
Extracción de valores importantes de un archivo JSON grande
Como experto en TI especializado en JSON, bash y archivos grandes, necesitamos extraer todos los valores de
importantField
de un archivo JSON de 8GB en un archivo separado de manera automática.Solución
Podemos dividir el archivo JSON de entrada en varios archivos utilizando el comando
split
y luego utilizargrep
para extraer los valores deimportantField
de cada archivo. Luego podemos unir los resultados utilizando el comandocat
y guardarlos en un archivo separado.Pasos
split
de la siguiente manera:Esto dividirá el archivo de entrada en varios archivos con nombres que comienzan con
out_
.grep
para extraer los valores deimportantField
de cada archivo de la siguiente manera:Esto extraerá todos los valores de
importantField
de cada archivo dividido y los guardará en un archivo separado llamadoimportant_fields.txt
.cat
y guardarlos en un archivo separado de la siguiente manera:Esto concatenará todos los valores de
importantField
en un solo archivo llamadoall_important_fields.txt
.Verificación de la división adecuada de los archivos
Necesitamos asegurarnos de que el comando
split
no divida el archivo de entrada en medio del par clave-valorimportantField
. Esto se puede hacer ejecutando el comandogrep
en los archivos divididos y comprobando si algún parimportantField
está dividido entre dos archivos.Esto mostrará el número de ocurrencias de
importantField
en cada archivo dividido. Luego podemos verificar manualmente si alguna ocurrencia está dividida entre dos archivos.Problemas de rendimiento con el comando grep
El comando
grep
tuvo problemas de rendimiento al ejecutarse en un archivo de 8GB. Esto se debió al gran uso de memoria que requería. Al ejecutarse en archivos de 2GB, terminó bastante rápido en unos 30 segundos. Esto se debe posiblemente al hecho de quegrep
primero carga toda la línea en memoria, lo cual utiliza la mitad de la RAM, y luego utiliza más memoria para sus cálculos internos, lo que hace que el sistema comience a utilizar la memoria SWAP, lo que a su vez causa un rendimiento lento antes de terminar el programa.Conclusión
Para extraer los valores de
importantField
de un archivo JSON grande, podemos dividir el archivo en varios archivos, extraer los valores de cada archivo dividido y unirlos en un solo archivo. También debemos asegurarnos de que la división se realice correctamente. El comandogrep
puede tener problemas de rendimiento al trabajar con archivos grandes.