Descompactar o arquivo gzip no lugar

1

Eu tenho um arquivo enorme (420 GB) compactado com gzip e quero descompactá-lo, mas meu disco rígido não tem espaço para armazenar todo o arquivo compactado e seu conteúdo.

Haveria uma maneira de descomprimi-lo "ao excluí-lo"?

Caso isso ajude, gzip -l diz que existe apenas um arquivo dentro (que é um arquivo tar que eu também terei que separar de alguma forma)

Obrigado antecipadamente!

    
por Noxbru 31.01.2017 / 14:23

3 respostas

3

Would there be a way of decompressing it 'while deleting it'?

Isso é o que você pediu. Mas pode não ser o que você realmente quer. Use a seu próprio risco.

Se o arquivo de 420GB estiver armazenado em um sistema de arquivos com suporte a arquivos esparso e furos (por exemplo, ext4 , xfs , mas não ntfs ), será possível ler um arquivo e liberar os blocos de leitura usando %código%. No entanto, se o processo for cancelado por algum motivo, pode não haver nenhuma maneira de recuperar, pois tudo o que resta é um arquivo parcialmente descompactado e meio descompactado. Não tente fazer isso sem fazer outra cópia do arquivo fonte primeiro.

Prova de conceito muito difícil:

# dd if=/dev/urandom bs=1M count=6000 | pigz --fast > urandom.img.gz
6000+0 records in
6000+0 records out
6291456000 bytes (6.3 GB, 5.9 GiB) copied, 52.2806 s, 120 MB/s
# df -h urandom.img.gz 
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           7.9G  6.0G  2.0G  76% /dev/shm
O arquivo

fallocate --punch-hole ocupa 76% do espaço disponível, por isso não pode ser descompactado diretamente. Pipe resultado descompactado para urandom.img.gz , para que possamos verificar mais tarde:

# gunzip < urandom.img.gz | md5sum
bc5ed6284fd2d2161296363edaea5a6d  -

Descompacte enquanto perfura: (isso é muito difícil sem qualquer verificação de erros)

total=$(stat --format='%s' urandom.img.gz) # bytes
total=$((1+$total/1024/1024)) # MiB
for ((offset=0; offset < $total; offset++))
do
    # read block
    dd bs=1M skip=$offset count=1 if=urandom.img.gz 2> /dev/null
    # delete (punch-hole) blocks we read
    fallocate --punch-hole --offset="$offset"MiB --length=1MiB urandom.img.gz
done | gunzip > urandom.img

Resultado:

# ls -alh *
-rw-r--r-- 1 root root 5.9G Jan 31 15:14 urandom.img
-rw-r--r-- 1 root root 5.9G Jan 31 15:14 urandom.img.gz
# du -hcs *
5.9G    urandom.img
0       urandom.img.gz
5.9G    total
# md5sum urandom.img
bc5ed6284fd2d2161296363edaea5a6d  urandom.img

A soma de verificação corresponde, o tamanho do arquivo de origem foi reduzido de 6 GB para 0 enquanto estava descompactado.

Mas há tantas coisas que podem dar errado ... melhor não fazer isso, ou se você realmente precisa, pelo menos use um programa que faça uma checagem de erros ainda melhor. O loop acima não garante que os dados foram lidos e processados antes de serem excluídos. Se md5sum ou dd retornar um erro por qualquer motivo, gunzip ainda o lançará com alegria ... por isso, se você precisar usar essa abordagem, escreva melhor um programa saner fallocate .

    
por 31.01.2017 / 15:18
0

Se você tiver um segundo disco rígido, poderá mover o arquivo compactado para lá e, em seguida, descompactá-lo e desarquivá-lo para onde desejar:

$ mv archive.gz /mnt/somedrive/
$ cd /where/it/should/go
$ tar xvzf /mnt/somedrive/archive.gz
    
por 31.01.2017 / 14:39
0

Depende do que você quer fazer com isso.

Se for um arquivo .tar.gz, você pode ver o conteúdo do piche sem descompactá-lo primeiro com tar --list -zf /path/to/file .

Então, se você quiser apenas alguns arquivos dentro do tgz, você pode extraí-los com tar -xzvf /path/to/file relative/path/to/files/inside/tar . Como sempre, você pode alterar o diretório de destino com -C .

Isso acontece porque mesmo que um .tar.gz seja na verdade um arquivo .tar compactado com gz, esse cenário é tão comum que o tar tem a opção de trabalhar com ele embutido, passando o sinalizador -z . Este sinalizador só funciona com gzip tho (e talvez bzip2 também, não tenho certeza), não com xz ou lz4.

Como uma resposta bônus, se o arquivo dentro do .gz não for um tar, você sempre pode canalizar a saída para um pager como menos, o que caberá na memória: gzcat /path/to/file | less

    
por 31.01.2017 / 15:07

Tags