¿Cómo XZ un directorio con TAR usando la compresión máxima?

116

Entonces necesito comprimir un directorio con compresión máxima.

¿Cómo puedo hacerlo xz? Quiero decir que también lo necesitaré tarporque no puedo comprimir un directorio solo xz. ¿Hay un revestimiento para producir, por ejemplo foo.tar.xz?

LanceBaynes
fuente
11
FWIW, man 1 xzdice it's not a good idea to blindly use -9 for everything like it often is with gzip(1) and bzip2(1). -7 ... -9 [...] These are useful only when compressing files bigger than 8 MiB, 16 MiB, and 32 MiB, respectively.RTFM para más información.
cychoi

Respuestas:

82

Suponiendo que xzrespeta el conjunto estándar de indicadores de línea de comandos, incluidos los indicadores de nivel de compresión, puede intentar:

tar -cf - foo/ | xz -9 -c - > foo.tar.xz 
Shadur
fuente
y esto usa el nivel de compresión máximo con XZ?
LanceBaynes
3
agregar -9 a xz lo hará máximo
bsd
23
-9ees el mejor nivel, pero llevará mucho tiempo
Krzysztof Krasoń
-9eno siempre le dará el mejor resultado - vea el punto 8 aquí rootusers.com/13-simple-xz-examples
KolonUK
1
Además, puede ver una mejora significativa si agrega --threads=0a xz
KolonUK
146

Con un GNU reciente taren bash o shell derivado:

XZ_OPT=-9 tar cJf tarfile.tar.xz directory

El interruptor j minúscula de tar usa bzip, el interruptor J mayúscula usa xz.

La XZ_OPTvariable de entorno le permite establecer xzopciones que no se pueden pasar a través de aplicaciones de llamada como tar.

Esto ahora es máximo .

Consulte man xzotras opciones que puede configurar ( -e/ --extreme podría darle algún beneficio de compresión adicional para algunos conjuntos de datos).

XZ_OPT=-e9 tar cJf tarfile.tar.xz directory
bsd
fuente
27
No, tu no. Ese es todo el punto. Puede configurar el entorno var solo para esa invocación. Puede exportarlo si lo desea, pero no tiene que hacerlo.
bsd
2
Estás asumiendo un shell bash-like para eso.
anddam
77
@anddam, eso es compatible con todos los shells de la familia Bourne (Bourne, ksh, mksh, pdksh, ash, dash, bash, yash, zsh) y rcy akanga. fish, csh, tcshY essiendo las principales conchas que no lo soportan. Allí, usarías el envcomando.
Stéphane Chazelas
1
Por lo tanto para establecer -9y -exz opta, desea XZ_OPT=-e9sino como @krzyk señaló, -e es extremadamente lenta
placas
44
Solo para el registro: XZ_OPTno es una característica implementada en tar. Es una característica de xz. Cuando se tarllama xz, la variable env simplemente se pasa.
Sven
14
XZ_OPT=-9e tar cJf tarfile.tar.xz directory

es incluso mejor que

XZ_OPT=-9 tar cJf tarfile.tar.xz directory
Evandro Jr
fuente
55
¿Cómo es esto mejor? ¿Qué hace la bandera e?
cxdf
2
option -e, --extremeModifique el preajuste de compresión (-0 ... -9) para que se pueda lograr una relación de compresión un poco mejor sin aumentar el uso de memoria del compresor o descompresor (excepción: el uso de memoria del compresor puede aumentar un poco con los preajustes -0 ... -2). La desventaja es que el tiempo de compresión aumentará dramáticamente (puede duplicarse fácilmente).
Evandro Jr
Entonces, si estoy comprimiendo alrededor de 80 GB de software en mi máquina (cuando quiero que todos los recursos de la computadora vayan al proceso de compresión por velocidad) -9no debería usar -9e, ¿sí?
nyxee
1
xz por defecto usa 1 núcleo / hilo, puede maximizarlo (acelerarlo) agregando -T0, por ejemploXZ_OPT="-9e -T0" tar -cJf ...
EkriirkE
10

Si tiene 16 GiB de RAM (y nada más en ejecución), puede intentar:

tar -cf - foo/ | xz --lzma2=dict=1536Mi,nice=273 -c - > foo.tar.xz 

Esto necesitará 1.5 GiB para la descompresión, y aproximadamente 11 veces más que para la compresión. Ajuste en consecuencia para menores cantidades de memoria.

Esto solo ayudará si los datos son realmente tan grandes, y en cualquier caso no ayudará TANTO , pero aún así ...

Si está comprimiendo archivos binarios, agregue --x86 como la primera opción xz. Si está jugando con archivos "multimedia" (audio sin comprimir o mapas de bits), puede probar con --delta = dist = 2 (experimente con el valor, los buenos valores para probar son 1..4).

Si te sientes muy aventurero, puedes intentar jugar con más opciones de LZMA, como

--lzma2=dict=1536Mi,nice=273,lc=3,lp=0,pb=2

(esta es la configuración predeterminada, puede probar valores entre 0 y 4, y lc + lp no debe exceder 4)

Para ver cómo se asignan los valores predeterminados predeterminados a estos valores, puede consultar el archivo fuente src / liblzma / lzma / lzma_encoder_presets.c. Sin embargo, no hay nada de mucho interés (-e establece la longitud agradable en 273 y también ajusta la profundidad).

Anónimo
fuente
6

Puede probar diferentes opciones, para mí -4e funciona mejor

tar cf - wam_GG_${dir}.nc | xz -4e > wam_GG_${dir}.nc.tar.xz 

Probé ejecutando:

$ tar -cf - wam_GG.nc | xz -4e > wam_GG.nc.xz
$ tar -cf - wam_GG.nc | xz -9e > wam_GG.nc.xz.2

Entonces, parece que la opción -4e funciona un poco mejor que -9e.

$ ll wam_GG.nc.xz*
-rw-rw-r--. 1 504 504 2707596 Jan 16  2015 wam_GG.nc.xz
-rw-rw-r--. 1 504 504 2708416 Jan 16  2015 wam_GG.nc.xz.2
Szymon Roziewski
fuente
3
Esto realmente no responde la pregunta. Esto es solo una observación de que para su pequeño conjunto de datos en particular, -4e ya obtiene la mejor compresión y, por lo tanto, los niveles más altos no obtienen más beneficios (e incluso una penalización muy leve).
psusi
¿Eres el mismo usuario que Szymon Roziewski ? Si es así, no publique varias respuestas. En cambio, edite su respuesta original. Si no puede acceder a su primera cuenta, consulte aquí cómo fusionar sus cuentas. Mientras tanto, estoy borrando su respuesta anterior e incluyéndola aquí.
terdon
Ok, he hecho un estudio más completo sobre eso. Lo que tengo está aquí. Elegí algunos archivos de mi disco duro e hice compresión con la opción -4e y -9e. Por lo tanto, es mejor encontrar su mejor solución usted mismo. Tenías razón, para algunos casos -9e es mejor, mientras que para otro no lo es:no difference = 660 4e better than 9e = 74 9e better than 4e = 17 total files = 751 tar 2 html 2 csv 2 xml 2 gz 2 ppt 2 eps 2 docx 2 gif 2 rpm 3 png 3 asv 3 xlsx 3 exe 3 rar 4 nc 4 txt 5 odt 6 xls 7 zip 7 doc 9 m 12 dat 17 other 109 pdf 133 135 jpg 270
Szymon Roziewski
(los comentarios pueden editarse solo durante 5 minutos)txt 109 txt/pdf 135
Szymon Roziewski
2
+1. Esto ayuda al OP a encontrar una manera de determinar la compresión máxima para tarusar archivos xz.
cychoi
5

tar --help : -I, --use-compress-program=PROG

tar -I 'xz -9' -cvf foo.tar.xz foo/  
tar -I 'gzip -9' -cvf foo.tar.gz foo/    

también comprimir con compresores externos:

tar -I 'lz4 -9' -cvf foo.tar.lz4 foo/
tar -I 'zstd -19' -cvf foo.tar.zst foo/

descomprimir compresores externos:

tar -I lz4 -xvf foo.tar.lz4  
tar -I zstd -xvf foo.tar.zst  

Listar compresores externos de archivo:

tar -I lz4 -tvf foo.tar.lz4
tar -I zstd -tvf foo.tar.zst
Goran Dragic
fuente
1
Esto parece una respuesta funcional, pero, tal como está, mejoraría enormemente si se arreglara su formato y se -Iagregara una explicación de la opción .
dhag
4

tarEl comando usa la Jbandera para los archivos xz. Un ejemplo:

tar -cJvf foo.tar.xz foo/

leonardoav
fuente
2
El Jya fue mencionado en la respuesta de Bdowning
Anthon
3

Para aquellos interesados, -e9es 0.4% más pequeño, 20% más lento en la compresión, 3% más lento para la descompresión, en comparación con -9una computadora portátil típica. Aquí están los tiempos de ejecución en la estructura del directorio del código fuente de Python.

Compresión:

$ Tbefore=`date +%s%3N` && XZ_OPT=-9 tar cJf python3.6.tar.9xz Python-3.6.0 && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"
43.87
$ Tbefore=`date +%s%3N` && XZ_OPT=-e9 tar cJf python3.6.tar.e9xz Python-3.6.0 && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"
53.861

Descompresión:

$ Tbefore=`date +%s%3N` && tar xf python3.6.tar.9xz && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"  && rm -rf Python-3.6.0
1.395
$ rm -rf Python-3.6.0
$ Tbefore=`date +%s%3N` && tar xf python3.6.tar.e9xz && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"  && rm -rf Python-3.6.0
1.443

Tamaño del archivo:

$ rm -rf Python-3.6.0
$ Tbefore=`date +%s%3N` && tar xf Python-3.6.0.tar.xz && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)" && rm -rf Python-3.6.0
1.49
$ ls -al ?ython*
-rw-rw-r-- 1 hobs hobs 16378500 Dec 23 13:06 python3.6.tar.9xz
-rw-rw-r-- 1 hobs hobs 16314420 Dec 23 13:05 python3.6.tar.e9xz
-rw-rw-r-- 1 hobs hobs 16805836 Dec 23 12:24 Python-3.6.0.tar.xz
placas
fuente
1
Elección de nombre de variable incorrecta, porque T0 es una opción para habilitar la archivación de subprocesos múltiples.
Dzenly
@Dzenly Tienes razón! ¡Gracias! Lo cambié
Hobs
2

Esta no es una respuesta exacta a su pregunta, pero podría usar un comando en lugar de dos:

7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on archive.7z dir1

agrega todos los archivos del directorio "dir1" al archivo archive.7z usando "ultras ettings"

Otros formatos soportados son: zip, gzip, bzip2 o tar. para esto solo reemplace 7zdespués -t.
--fuenteman 7z

NOTA: no use este comando para hacer una copia de seguridad de los archivos de su sistema, excepto los archivos personales porque el formato 7z no almacena los permisos del sistema de archivos .

Edward Torvalds
fuente
55
La pregunta era sobre xz, no sobre 7z, a pesar de que ambos usan compresión LZMA.
Amedee Van Gasse
2

En una máquina multinúcleo de la versión v5.2.0 de xz-utils, verifique:

-T, --threads=NUM   use at most NUM threads; the default is 1; set to 0

Si desea utilizar el número máximo de núcleos y la compresión máxima:

export XZ_DEFAULTS="-9 -T 0 "

O establezca -T en la cantidad de núcleos que desea usar.

Entonces:

tar cJf target.tar.xz source

También esto puede ser útil para elegir el nivel de compresión:

https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO

mirix
fuente
1

Si desea que esto se complete más rápido, utilizando múltiples subprocesos, pero sin ralentizar su sistema mientras realiza otro trabajo, intente agregar -Tndonde n es cuántos subprocesos desea usar, así como nicedisminuir la compresión a la prioridad de inactividad.

Modelo (para 4 hilos):

tar c foo/ | nice -n19 xz -9 -T4 > foo.tar.xz

Intente verlo topo htopcuando lo haga en un directorio grande (varios GB). Con suerte, debería ver varios xzhilos con un buen valor de 19 (prioridad más baja).

También eliminé esto para que sea tan claro como sensato, como por ejemplo: las -f -otras respuestas simplemente no son necesarias, ya que tarel resultado predeterminado es stdout.

También puede realizar niceel proceso de tar, pero nunca lo he encontrado necesario, ya que xzsiempre obstaculiza la CPU para la tubería.

Nota práctica, rara vez lo uso xz -9para algo, no tanto por la CPU o el tiempo, sino por las altas demandas de memoria. Eche un vistazo a https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO#Memory_requirements_on_compression . El xzcompresor, como bzip2, pero a diferencia gzip, usa más memoria para factores de compresión más altos. En conjunto, con eso xzusa mucha más memoria que cualquier otro compresor, puede usar fácilmente más de 600 MB de memoria. Y si utiliza el -Tpara habilitar la compresión roscada, las demandas de memoria aumentan aún más. Solo algo a tener en cuenta, como si está ejecutando un pequeño servicio en una pequeña VM con 1-2 GB de memoria, podría causar un impacto inadvertido.

Joshua Huber
fuente
1

En Mac OS X, un enfoque alternativo para pasar el parámetro tares usar una --options=bandera. Por ejemplo,

tar Jcvf targetFileName.tar.xz --options='compression-level=9' directoryName
Samuel Li
fuente