¿Cómo debo combinar muchos archivos comprimidos en un archivo?

10

Tengo unos cientos de .tar.xzarchivos que son casi idénticos (son volcados diarios de la base de datos y la base de datos cambia lentamente).

Creo que debido a las similitudes en los archivos sin comprimir, se comprimirán muy bien, y las pruebas a pequeña escala han demostrado que comprimir cualquier número de estos archivos sin comprimir crea un archivo un poco más grande que uno de ellos.

Mi problema es que todos los archivos sin comprimir serían unos pocos terabytes (la relación de compresión es de aproximadamente 25: 1) y no tengo tanto espacio en disco para usar como área de trabajo.

¿Hay alguna manera de procesar los archivos comprimidos individuales de uno en uno, agregándolos a un único archivo y conservando los beneficios de comprimirlos?

jl6
fuente
¿Has intentado crear una secuencia de comandos para descomprimir un archivo, agregar todos los archivos a un archivo dado y luego pasar al siguiente?
darnir

Respuestas:

10

Dado que los archivos tar son un formato de transmisión, puede catjuntar dos de ellos y obtener un resultado casi correcto, no necesita extraerlos en el disco para hacer esto. Puede descomprimir (solo) los archivos, concatenarlos juntos y volver a comprimir esa secuencia:

xzcat *.tar.xz | xz -c > combined.tar.xz

combined.tar.xzserá un tarball comprimido de todos los archivos en los tarballs componentes que solo está ligeramente dañado. Para extraer, tendrá que usar la --ignore-zerosopción (en GNU tar), porque los archivos tienen un marcador de "fin de archivo" que aparecerá en el medio del resultado. Aparte de eso, sin embargo, todo funcionará correctamente.

GNU tartambién admite un --concatenatemodo para producir archivos combinados. Tiene las mismas limitaciones que las anteriores, debe usar --ignore-zerospara extraer, pero no funciona con archivos comprimidos. Puede construir algo para engañarlo para que funcione utilizando la sustitución de procesos, pero es una molestia y aún más frágil.

Si hay archivos que aparecen más de una vez en diferentes archivos tar, esto no funcionará correctamente, pero tiene ese problema independientemente. De lo contrario, esto le dará lo que desea: canalizar la salida xzes cómo tarcomprime su salida de todos modos.


Si los archivos que solo funcionan con una tarimplementación en particular no son adecuados para sus propósitos, rsu amigo puede agregarlos al archivo :

tar cJf combined.tar.xz dummy-file
for x in db-*.tar.xz
do
    mkdir tmp
    pushd tmp
    tar xJf "../$x"
    tar rJf ../combined.tar.xz .
    popd
    rm -r tmp
done

Esto solo extrae un único archivo a la vez, por lo que el espacio de trabajo está limitado al tamaño de los contenidos de un único archivo. La compresión se transmite de la misma manera que lo hubiera hecho si hubiera hecho el archivo final de una vez, por lo que será tan bueno como podría haber sido. Hace una gran cantidad de exceso de descompresión y recompresión que lo hará más lento que las catversiones, pero el archivo resultante funcionará en cualquier lugar sin ningún soporte especial.

Tenga en cuenta que, dependiendo de lo que desee exactamente, basta con agregar los archivos tar sin comprimir a un archivo. Comprimirán (casi) exactamente así como sus contenidos en un solo archivo, y reducirá la sobrecarga de compresión para cada archivo. Esto se vería algo así como:

tar cJf combined.tar.xz dummy-file
for x in db-*.tar.xz
do
    xz -dk "$x"
    tar rJf combined.tar.xz "${x%.xz}"
    rm -f "${x%.xz}"
done

Esto es un poco menos eficiente en términos del tamaño comprimido final porque hay encabezados de alquitrán adicionales en la secuencia, pero ahorra algo de tiempo en extraer y volver a agregar todos los archivos como archivos. Terminarías combined.tar.xzconteniendo muchos db-*.tararchivos (sin comprimir) .

Michael Homer
fuente
Gracias, su segunda opción parece adecuada para mi propósito, pero ¿podría dar más detalles sobre su último párrafo? ¿A qué se parecería?
jl6
@ jl6: ver edición.
Michael Homer
Lo siento, solo pude probar esto. Su segundo método me da este error:tar: Cannot update compressed archives
jl6