Desarquivar arquivo enquanto reduz o tamanho do arquivo?

6

O dilema: eu tenho um arquivo de 10GB e um disco rígido de 20GB. Quando vou descompactar / desarquivar o arquivo, o disco rígido fica cheio e o processo falha.

Pergunta: No servidor ubuntu 12.04 / linux existe uma maneira de desarquivar um arquivo enquanto reduzo o tamanho do arquivo?

Ethan Willis
fonte
Você não pode modificar o tamanho de um arquivo existente dessa maneira. Alterar o tamanho do arquivo exigiria a remoção do conteúdo do arquivo que já requer mais de 10 GB de dados. Você precisa aumentar o armazenamento overal no seu servidor, 10 GB é o tamanho do tamanho comprimido, é provável que 30-40% maior do que isso.
Ramhound
Você tem certeza de que a exclusão de arquivos de um arquivo requer que eles sejam desarquivados primeiro?
Ethan Willis
2
Você pode extrair cada arquivo, um por um, e depois excluir o arquivo dentro do arquivo. Então eu entendo aumentando o tamanho do armazenamento está fora de questão?
Ramhound
Está fora de questão. E o que você acabou de dizer é exatamente o tipo de solução que estou procurando. A única pergunta é como? (sem fazer isso manualmente)
Ethan Willis
A única maneira de saber como fazer o que você quer seria à mão. Você tem certeza de que os dados descompactados podem até caber no sistema? Você está olhando para 14-15Gb descompacta de dados mais provável, mais os dados compactados do maior arquivo. A matemática simplesmente não faz sentido.
Ramhound

Respostas:

6

Aqui está outra solução. Ele não permite que você extraia arquivos individuais de um arquivo e reduza seu tamanho, mas permite que você extraia todos os arquivos reduzindo o tamanho do arquivo à medida que você vai:

#!/bin/sh

# $1, the first paramter, is the .tar.gz file to unarchive

(
    size=$(wc -c $1)
    offset=0
    bs=4096
    while [[ $size > $offset ]]; do
        dd if=$1 bs=$bs count=1 skip=$offset status=none
        fallocate -p -o $offset -l $bs $1
        offset=$(( $offset + $bs ))
    done
) | tar xz

Salvar isso em um arquivo como, por exemplo, untar_and_destroy.sh e execute como:

untar_and_destroy.sh whatever.tar.gz

O que isto faz é dar parte do .tar.gz file to tar, pede ao Linux para desalocar essa parte do arquivo, e então repete para a próxima parte. Quando tiver terminado, ls -l vai dizer o .tar.gz arquivos tem o mesmo tamanho de antes, mas du irá relatar seu tamanho como 0. Isso ocorre porque o .tar.gz foi transformado em um arquivo esparso, com o mesmo tamanho de antes, mas como todos os 0s que não precisam ser armazenados no disco.

Não use isso na produção ou em qualquer lugar onde esse arquivo excluído seja ruim. Isso torna o arquivo ilegível assim que é iniciado, por isso, se algo der errado, por exemplo, você fica sem espaço no disco rígido enquanto extrai, você não terá uma segunda chance de executar isso.

wingedsubmariner
fonte
Este é o tipo de resposta que eu estava procurando. Se fosse possível não corromper o arquivo que seria ainda melhor, mas acho que isso pode não ser uma possibilidade com minhas restrições.
Ethan Willis
Você precisa count=1 opção em dd, caso contrário, ele irá mostrar o arquivo inteiro na primeira iteração do loop, que não libera o espaço em disco durante a execução do comando. Além disso, eu reformularia tar xfz - para tar xz.
Zouppen
@Zouppen Bons pontos, eu editei aqueles em.
wingedsubmariner
2

Eu não conheço nenhuma ferramenta que possa fazer isso, e não acho que nenhum dos formatos comuns de arquivamento suportem isso.

Uma solução possível para o seu problema seria manter o arquivo em uma máquina diferente e encaminhá-lo para a máquina em que você deseja descompactá-lo. Por exemplo, você poderia executar este comando na máquina com o arquivo:

cat archive.tar.gz | ssh YOUR_SERVER tar xfz -

O arquivo será transmitido para o tar processo em execução no servidor, que irá descompactá-lo sem precisar que o arquivo esteja presente no servidor.

wingedsubmariner
fonte
Esta sugestão, e todas as outras, é muito legal. No entanto, isso não resolve a questão da necessidade de fazê-lo na própria máquina. A velocidade de rede da máquina torna impraticável mover uma quantidade tão grande de dados de maneira oportuna.
Ethan Willis
então possivelmente um formato de arquivo que permitiria que os arquivos fossem removidos do arquivo sem a necessidade de fazer uma segunda cópia do arquivo seria necessário?
Ethan Willis
A única maneira de fazer isso funcionar seria extrair arquivos do final do arquivamento e diminuir o tamanho do arquivo. Você pode cortar o tar formato para permitir que você faça isso, mas não depois de ter sido compactado. Realmente não faria muito sentido usar um arquivo nessa situação, em vez de apenas os arquivos em si.
wingedsubmariner
2

Embora possa ser impraticável expandir o armazenamento primário, talvez você possa extrair o conteúdo do arquivo para um dispositivo de armazenamento externo.

Como alternativa, gere uma lista de arquivos no archive e, em seguida, escreva um script que extraia alguns deles. Mova esses arquivos para a nuvem, selecione outro lote para extrair, ensaboar, enxaguar, repetir.

Mas, todo aplicativo de arquivamento que eu conheço tem que ter o arquivo original intacto enquanto cria um novo arquivo sem o que você não quer, então o armazenamento externo será muito, muito útil.

K7AAY
fonte
A segunda solução que você oferece é mais do que eu estou procurando. No entanto, movê-lo para a nuvem e voltar é impraticável. Isso precisa ser feito no lugar.
Ethan Willis