Dividir archivos usando tar, gz, zip o bzip2 [cerrado]

144

Necesito comprimir un archivo grande de aproximadamente 17-20 GB. Necesito dividirlo en varios archivos de alrededor de 1 GB por archivo.

Busqué una solución a través de Google y encontré formas de usar splity catcomandos. Pero no funcionaron para archivos grandes en absoluto. Además, no funcionarán en Windows; Necesito extraerlo en una máquina con Windows.

Aka
fuente
3
Siento tu dolor, pero esto no parece estar relacionado con la programación.
Jason S
1
Muchos programas de compresión (p. Ej., Como 7-Zip) pueden dividir el archivo comprimido en volúmenes de un tamaño específico para facilitar la distribución.
Martin Liversage
Esto pertenece a superuser.com, pero me dicen que la beta privada no comienza hasta mañana.
JesperE el
¿Puedo preguntar por qué necesita ese archivo comprimido?
Jan Jungnickel
Si una de las dos soluciones viables publicadas aquí no funciona, necesitará una solución de programación.
Joshua el

Respuestas:

253

Puede usar el splitcomando con la -bopción:

split -b 1024m file.tar.gz

Se puede volver a montar en una máquina con Windows utilizando la respuesta de @ Joshua .

copy /b file1 + file2 + file3 + file4 filetogether

Editar : como dijo @Charlie en el comentario a continuación, es posible que desee establecer un prefijo explícitamente porque usará lo xcontrario, lo que puede ser confuso.

split -b 1024m "file.tar.gz" "file.tar.gz.part-"

// Creates files: file.tar.gz.part-aa, file.tar.gz.part-ab, file.tar.gz.part-ac, ...

Editar : Editar la publicación porque la pregunta está cerrada y la solución más efectiva está muy cerca del contenido de esta respuesta:

# create archives
$ tar cz my_large_file_1 my_large_file_2 | split -b 1024MiB - myfiles_split.tgz_
# uncompress
$ cat myfiles_split.tgz_* | tar xz

Esta solución evita la necesidad de utilizar un archivo grande intermedio al (des) comprimir. Use la opción tar -C para usar un directorio diferente para los archivos resultantes. Por cierto, si el archivo consta de un solo archivo, se podría evitar tar y solo se usaría gzip:

# create archives
$ gzip -c my_large_file | split -b 1024MiB - myfile_split.gz_
# uncompress
$ cat myfile_split.gz_* | gunzip -c > my_large_file

Para Windows, puede descargar versiones portadas de los mismos comandos o usar cygwin.

matpie
fuente
77
si no agrega un prefijo como último argumento después del nombre de archivo para dividir, obtendrá la salida en archivos llamados xaa, xab, xac, xad ....
Charlie
@ Charlie, gracias, actualicé mi respuesta.
matpie
2
En realidad, el uso -b 1024MiBdio un error de que era un número de bytes no válido. Utilizando --bytes=1024mobras.
Brian
Y no tiene que usar catpara volver a armar el archivo. Puede usar copy /b file1 + file2 + etc..en Windows, luego copiar de nuevo a Linux y tar puede leer el tarball reensamblado. Solo lo intenté.
Brian
1
Split tiene la opción --numeric-suffixes: usar sufijos numéricos en lugar de alfabéticos.
Dr. Jan-Philip Gehrcke
27

Si se está separando de Linux, aún puede volver a ensamblar en Windows.

copy /b file1 + file2 + file3 + file4 filetogether
Joshua
fuente
También puede usar copy /b file* filetogether: support.microsoft.com/kb/71161
eug
55
Eso funciona correctamente solo en NTFS y si los archivos ya están en orden de clasificación NTFS. Pruébelo en FAT o FAT32 = boom.
Joshua
¡+1 asegúrese de que los archivos estén en el orden correcto!
Brian
@Joshua Para ser justos, si no lo son, has hecho un mal trabajo al nombrar.
jpmc26
@ jpmc26: ¿Conoces los malos hábitos de reordenamiento de directorios de FAT32?
Joshua
8

El código probado, inicialmente crea un único archivo de almacenamiento, luego lo divide:

 gzip -c file.orig > file.gz
 CHUNKSIZE=1073741824
 PARTCNT=$[$(stat -c%s file.gz) / $CHUNKSIZE]

 # the remainder is taken care of, for example for
 # 1 GiB + 1 bytes PARTCNT is 1 and seq 0 $PARTCNT covers
 # all of file
 for n in `seq 0 $PARTCNT`
 do
       dd if=file.gz of=part.$n bs=$CHUNKSIZE skip=$n count=1
 done

Esta variante omite la creación de un solo archivo de almacenamiento y va directamente a la creación de partes:

gzip -c file.orig |
    ( CHUNKSIZE=1073741824;
        i=0;
        while true; do
            i=$[i+1];
            head -c "$CHUNKSIZE" > "part.$i";
            [ "$CHUNKSIZE" -eq $(stat -c%s "part.$i") ] || break;
        done; )

En esta variante, si el tamaño del archivo del archivo es divisible por $CHUNKSIZE, entonces el último archivo parcial tendrá un tamaño de archivo de 0 bytes.

Adrian Panasiuk
fuente
1
Eso es lo splitque ya hace.
ephemient
1
efímero Oye, he cavado alguna publicación en busca de ESO. No tengo comandos / binarios divididos ni comprimidos en un determinado dispositivo, y este ha funcionado perfectamente. Prepararé este código para que funcione como comando dividido :). Muchas gracias @Adrian Panasiuk. Eso es perfecto para mí.
m3nda
@ erm3nda De nada, ¡me alegra que ayude!
Adrian Panasiuk
Pero, lo probé y el resultado fue un archivo completo, no dividido. ¿Cómo puede ser? Era un archivo grande en un dispositivo pequeño, por lo que fue un proceso largo. Pruebe sus soluciones mientras publica :(
m3nda
@ erm3nda ¡Nunca nos dijo que necesita evitar crear un archivo temporal! Por favor vea la segunda variante!
Adrian Panasiuk