Estoy seguro de que alguien ha tenido la siguiente necesidad: ¿cuál es una forma rápida de dividir un archivo .gz enorme por línea? El archivo de texto subyacente tiene 120 millones de filas. No tengo suficiente espacio en disco para comprimir todo el archivo a la vez, así que me preguntaba si alguien conoce algún script o herramienta bash/perl que pueda dividir el archivo (ya sea .gz o .txt interno) en 3 archivos de 40 minutos de línea. . es decir, llamándolo así:
bash splitter.sh hugefile.txt.gz 4000000 1
would get lines 1 to 40 mn
bash splitter.sh hugefile.txt.gz 4000000 2
would get lines 40mn to 80 mn
bash splitter.sh hugefile.txt.gz 4000000 3
would get lines 80mn to 120 mn
Quizás hacer una serie de estos sea una solución o gunzip -c requeriría suficiente espacio para descomprimir todo el archivo (es decir, el problema original): gunzip -c hugefile.txt.gz | cabeza 4000000
Nota: no puedo obtener un disco adicional.
¡Gracias!
Respuesta1
La mejor forma de hacerlo depende de lo que quieras:
- ¿Quieres extraer una sola parte del archivo grande?
- ¿O quieres crear todas las piezas de una sola vez?
Si quieres ununa sola parte del archivo, tu idea de usar gunzip
y head
es correcta. Puedes usar:
gunzip -c hugefile.txt.gz | head -n 4000000
Eso generaría las primeras 4000000 líneas en la salida estándar; probablemente desee agregar otra tubería para hacer algo con los datos.
Para obtener las otras partes, usarías una combinación de head
y tail
, como:
gunzip -c hugefile.txt.gz | head -n 8000000 |tail -n 4000000
para conseguir el segundo bloque.
¿Quizás hacer una serie de estos sea una solución o gunzip -c requeriría suficiente espacio para descomprimir todo el archivo?
No, gunzip -c
no requiere espacio en disco: hace todo en la memoria y luego lo transmite a la salida estándar.
Si quieres creartodas las partes de una vez, es más eficiente crearlos todos con un solo comando, porque entonces el archivo de entrada solo se lee una vez. Una buena solución es utilizar split
; consulte la respuesta de Jim Mcnamara para obtener más detalles.
Respuesta2
tubería para dividir use gunzip -c o zcat para abrir el archivo
gunzip -c bigfile.gz | split -l 400000
Agregue especificaciones de salida al comando de división.
Respuesta3
Mientras trabaja en una secuencia (no rebobinable), querrá utilizar la forma de cola '+N' para obtener líneas que comiencen desde la línea N en adelante.
zcat hugefile.txt.gz | head -n 40000000
zcat hugefile.txt.gz | tail -n +40000001 | head -n 40000000
zcat hugefile.txt.gz | tail -n +80000001 | head -n 40000000
Respuesta4
Divida directamente el archivo .gz en archivos .gz:
zcat bigfile.gz | split -l 400000 --filter='gzip > $FILE.gz'
Creo que esto es lo que quería OP, porque no tiene mucho espacio.