Como XZ um diretório com TAR usando a compressão máxima?

116

Então, eu preciso compactar um diretório com a compactação máxima.

Como posso fazer isso xz? Quero dizer, vou precisar tartambém porque não consigo compactar um diretório apenas xz. Existe um oneliner para produzir, por exemplo foo.tar.xz?

LanceBaynes
fonte
11
FWIW, man 1 xzdiz 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 mais informações.
cychoi

Respostas:

82

Supondo que xzhonre o conjunto padrão de sinalizadores de linha de comando - incluindo sinalizadores de nível de compactação, você pode tentar:

tar -cf - foo/ | xz -9 -c - > foo.tar.xz 
Shadur
fonte
e isso usa nível máximo de compressão com XZ?
precisa saber é o seguinte
3
adicionar -9 ao xz tornará o máximo
2212 bsd
23
-9eé o melhor nível, mas vai demorar muito tempo
Krzysztof Krasoń
-9enem sempre lhe dará o melhor resultado - consulte o ponto 8 aqui rootusers.com/13-simple-xz-examples
KolonUK
1
Além disso, você poderá ver uma melhoria significativa se adicionar --threads=0a xz
KolonUK
146

Com um GNU recente tarno bash ou no shell derivado:

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

o switch j minúsculo do tar usa bzip, o switch J maiúsculo usa xz.

A XZ_OPTvariável de ambiente permite definir xzopções que não podem ser transmitidas por aplicativos de chamada como tar.

Agora é o máximo .

Consulte man xzoutras opções que você pode definir ( -e/ --extreme pode fornecer benefícios adicionais de compactação para alguns conjuntos de dados).

XZ_OPT=-e9 tar cJf tarfile.tar.xz directory
bsd
fonte
27
Não você não. Esse é o ponto. Você pode definir o ambiente var apenas para essa chamada. Você pode exportá-lo se quiser, mas não precisa.
BSD
2
Você está assumindo o shell bash para isso.
anddam
7
@anddam, que é suportado por todas as conchas da família Bourne (Bourne, ksh, mksh, pdksh, ash, dash, bash, yash, zsh) e rce akanga. fish, csh, tcshE essendo os principais reservatórios que não suportam isso. Lá, você usaria o envcomando
Stéphane Chazelas
1
Então, para definir ambos -9e -exz opts, você quer, XZ_OPT=-e9mas como @krzyk apontou, -e é extremamente lento
hobs
4
Apenas para constar: XZ_OPTnão é um recurso implementado no tar. É uma característica do xz. Quando tarchamadas xz, a variável env é simplesmente transmitida.
Sven
14
XZ_OPT=-9e tar cJf tarfile.tar.xz directory

é ainda melhor que

XZ_OPT=-9 tar cJf tarfile.tar.xz directory
Evandro Jr
fonte
5
Como isso é melhor? O que a bandeira e faz?
Cxdf 6/08/2015
2
option -e, --extremeModifique a predefinição de compressão (-0 ... -9) para que seja possível obter uma taxa de compressão um pouco melhor sem aumentar o uso de memória do compressor ou descompressor (exceção: o uso de memória do compressor pode aumentar um pouco com as predefinições -0 ... -2). A desvantagem é que o tempo de compactação aumentará drasticamente (pode facilmente dobrar).
Evandro Jr
Então, se eu estiver compactando cerca de 80 GB de software na minha máquina (quando eu quiser que todos os recursos dos computadores passem para o processo de compactação por velocidade) , -9não devo usá-lo -9e, sim?
precisa saber é
1
xz por padrão usa 1 núcleo / thread, você pode maximizar isso (acelerar tudo) adicionando -T0, por exemploXZ_OPT="-9e -T0" tar -cJf ...
EkriirkE 28/01
10

Se você tiver 16 GiB de RAM (e nada mais estiver em execução), poderá tentar:

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

Isso precisará de 1,5 GiB para descompactação e cerca de 11x para compactação. Ajuste adequadamente para quantidades menores de memória.

Isso só ajudará se os dados forem realmente grandes e, em qualquer caso, não ajudará MUITO , mas ainda assim ...

Se você estiver compactando binários, adicione --x86 como a primeira opção xz. Se você estiver reproduzindo arquivos "multimídia" (áudio não compactado ou bitmaps), poderá tentar com --delta = dist = 2 (experimente com valor, bons valores para tentar são 1..4).

Se você estiver se sentindo muito aventureiro, tente jogar com mais opções de LZMA, como

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

(essas são as configurações padrão, você pode tentar valores entre 0 e 4 e lc + lp não deve exceder 4)

Para ver como as predefinições padrão são mapeadas para esses valores, você pode verificar o arquivo de origem src / liblzma / lzma / lzma_encoder_presets.c. Nada de muito interesse lá (-e define o bom comprimento para 273 e também ajusta a profundidade).

Anônimo
fonte
6

Você pode tentar opções diferentes, para mim -4e funciona melhor

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

Eu testei executando:

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

Portanto, parece que a opção -4e funciona um pouco melhor 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
fonte
3
Isso realmente não responde à pergunta. Isso é apenas uma observação de que, para o seu pequeno conjunto de dados específico, -4e já obtém a melhor compactação e, portanto, os níveis mais altos não recebem mais nenhum benefício (e até uma penalidade cada vez menor).
Psusi
Você é o mesmo usuário como Szymon Roziewski ? Nesse caso, não poste várias respostas. Em vez disso, edite sua resposta original. Se você não conseguir acessar sua primeira conta, consulte aqui para saber como mesclar suas contas. Enquanto isso, excluo sua resposta anterior e a incluo aqui.
terdon
Ok, eu fiz um estudo mais abrangente sobre isso. O que eu tenho está aqui. Escolhi alguns arquivos do meu disco rígido e fiz a compactação com as opções -4e e -9e. Portanto, é melhor encontrar a melhor solução sozinho. Você estava certo, em alguns casos -9e é melhor, enquanto em outros não é: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 20/15/15
(comentários podem ser editados somente por 5 minutos)txt 109 txt/pdf 135
Szymon Roziewski
2
+1. Isso ajuda o OP a encontrar uma maneira de determinar a compactação máxima para tararquivos usando 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/    

também comprima com compressores externos:

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

descomprimir compressores externos:

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

lista de compressores externos de arquivo morto:

tar -I lz4 -tvf foo.tar.lz4
tar -I zstd -tvf foo.tar.zst
Goran Dragic
fonte
1
Isso parece ser uma resposta funcional, mas, como é, seria bastante aprimorada com a formatação corrigida e a explicação da opção -Iadicionada.
dhag
4

tarO comando usa Jsinalizador para arquivos xz. Um exemplo:

tar -cJvf foo.tar.xz foo/

leonardoav
fonte
2
O Jjá foi mencionado na resposta do bdowning
Anthon
3

Para os interessados, -e9é 0,4% menor, 20% mais lento na compressão, 3% mais lento na descompressão, em comparação com -9um laptop típico. Aqui está o tempo executado na estrutura do diretório de código fonte do Python.

Compressão:

$ 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

Descompressão:

$ 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

Tamanho do arquivo:

$ 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
fogão
fonte
1
Escolha incorreta do nome da variável, porque T0 é a opção para ativar a arquivação multithread.
Dzenly
@ Dzenly Você está certo! Obrigado! Mudou isso.
hobs
2

Esta não é uma resposta exata para sua pergunta, mas você pode usar um comando em vez de dois:

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

adiciona todos os arquivos do diretório "dir1" para arquivar archive.7z usando "ultras ettings"

outros formatos suportados são: zip, gzip, bzip2 ou tar. para isso basta substituir 7zdepois -t.
--fonteman 7z

NOTA: não use este comando para fazer backup dos arquivos do sistema, exceto os arquivos pessoais, porque o formato 7z não armazena as permissões do sistema de arquivos .

Edward Torvalds
fonte
5
A questão era sobre xz, não sobre 7z, embora ambos usem compressão LZMA.
Amedee Van Gasse
2

Em uma máquina multicore da versão v5.2.0 do xz-utils, verifique:

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

Se você deseja usar o número máximo de núcleos e a compressão máxima:

export XZ_DEFAULTS="-9 -T 0 "

Ou defina -T para o número de núcleos que você deseja usar.

Então:

tar cJf target.tar.xz source

Além disso, isso pode ser útil para escolher o nível de compactação:

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

mirix
fonte
1

Se você deseja que isso seja concluído mais rapidamente, usando vários encadeamentos, mas sem desacelerar o sistema enquanto você executa outro trabalho, tente adicionar -Tnonde n é quantos encadeamentos você deseja usar, além nicede rebaixar a compactação para a prioridade ociosa.

Modelo (para 4 linhas):

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

Tente assistir topou htopquando você fizer isso em um grande diretório (vários GB). Esperamos que você veja vários xzthreads com o valor Nice de 19 (prioridade mais baixa).

Eu também reduzi isso de maneira mais concisa e sensível, como: as -f -outras respostas simplesmente não são necessárias, pois tara saída padrão é stdout.

Você também pode niceexecutar o processo tar, mas nunca achei necessário, pois xzsempre afunila a CPU do pipeline.

Nota prática, eu raramente uso xz -9para qualquer coisa, não tanto devido à CPU ou ao tempo, mas devido às altas demandas de memória. Dê uma olhada em https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO#Memory_requirements_on_compression . O xzcompressor, assim bzip2como o contrário gzip, usa mais memória para fatores de compressão mais altos. Juntando isso, que xzusa muito mais memória do que qualquer outro compressor, você pode usar facilmente mais de 600 MB de memória. E se você usar o -Tpara ativar a compactação encadeada, as demandas de memória aumentam ainda mais. Apenas algo a ter em conta, como se você estiver executando algum serviço pequeno em uma pequena VM com memória de 1-2 GB, poderá causar um impacto inadvertido.

Joshua Huber
fonte
1

No Mac OS X, uma abordagem alternativa para passar o parâmetro taré usar um --options=sinalizador. Por exemplo,

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