Estimando o tamanho do arquivo compactado usando um parâmetro de lista

3

Atualmente, estou compactando uma lista de arquivos de um diretório no seguinte formato:

tar -cvjf test_1.tar.gz -T test_1.lst --no-recursion

O comando acima comprimirá apenas os arquivos mencionados na lista. Eu estou fazendo isso porque essa lista é gerada de forma que cabe um DVD. No entanto, durante a compactação, a taxa de compactação diminui o tamanho estimado do arquivo e ainda há muito espaço no DVD. Isso é algo como um algoritmo Knapsack.

Gostaria de estimar o tamanho do arquivo compactado e adicionar mais arquivos à lista. Descobri que é possível estimar o tamanho do arquivo usando o seguinte comando:

tar -cjf - Folder/ | wc -c

Este comando não recebe um parâmetro de lista. Existe uma maneira de estimar o tamanho do arquivo compactado? Eu também estou olhando para opções como scripts perl etc.

Editar:

Acho que devo fornecer mais informações, já que tenho feito muita pesquisa na web. Me deparei com um script perl ( Link ) que meio que emula o algoritmo Knapsack.

O problema atual com o script mencionado acima é que ele divide os arquivos em seu estado original. Quando eu comprimir os arquivos depois de dividi-los, há oportunidades para adicionar mais arquivos que considero ineficientes.

Existem duas maneiras de resolver a ineficiência:

a) Compacte arquivos individuais e salve-os em um diretório usando um script. O arquivo compactado poderia fornecer uma estimativa melhor. Eu poderia gerar um script usando uma pasta de arquivos compactados e usá-los nos não compactados.

b) Verifique se o tamanho do arquivo compactado é menor que o tamanho requerido. Nesse caso, devo continuar adicionando arquivos até que eu atenda ao requisito. No entanto, a adição de novos arquivos ao arquivo compactado é um problema de otimização por si só.

    
por Sai 19.03.2012 / 21:06

1 resposta

1

Editar 2:

Eu releio sua pergunta e descobri uma nova maneira de interpretá-la. É simples encontrar o tamanho de um arquivo após a compactação, usando algo como bzip2 -k $file | wc -c em cada arquivo. Isso, no entanto, não resolverá seu problema, pois você não está interessado no tamanho de cada arquivo compactado, mas no tamanho compactado de um tarball que contém todos os seus arquivos (e quanto ele aumenta se você adicionar um arquivo específico). A diferença de tamanho da compactação não é linear , mas, de fato, bastante imprevisível, de modo que um é um preditor ruim para o segundo.

Um exemplo são dois arquivos idênticos de 10 MiB, em que ambos compactam individualmente para 1 MiB e um tarball contendo ambos também comprime para 1 MiB.

Resposta original

Acredito que a solução comum é apenas dividir os dados compactados com split , o que significa que você precisa de todos os discos resultantes disponíveis se quiser recuperar um arquivo de qualquer um deles. Eu acho que tar tem um mecanismo de divisão embutido, mas funciona apenas na quantidade de dados descomprimidos, o que dá resultados ruins com compactação e arquivos não homogêneos.

Uma solução diferente (longe da perfeição) funciona se você pode ter intervenção manual e pode ser suficiente. Funciona melhor se os seus arquivos forem grandes em comparação com o tamanho de volume desejado

Eu sugiro que você tenha um tamanho de volume de destino, em MiB. No exemplo, uso 700 MiB.

Se você correr

tout="/tmp/09b00c50a9625deeb1089b3c4358c5e5" #or something else
csize="7" # in MiB
mkfifo "$tout"
tar -cvj ~/ 2>"$tout" | dd bs=1M count="$csize" of=/dev/null iflag=fullblock 2>/dev/null &
tail -20 "$tout" | xargs -n 1 ls -ld
rm "$tout"

tar imprimirá todos os arquivos que tentar compactar no pipe, até que dd tenha recebido 700 MiB de dados compactados. tail lê os últimos 20 arquivos que tar tentou compactar do fifo.

O último arquivo impresso (pelo menos) não poderá caber no tamanho do seu volume. Devido ao cache em tar e bzip2 , vários dos outros últimos arquivos podem não se adequar a ambos, portanto, talvez seja necessário experimentar um pouco com quantos deles você pula. Se todos os arquivos forem muito pequenos, você pode ter que dizer a tail para imprimir mais de 20 deles para ver o que excede o limite.

Editar:

Você pode até gravar os nomes dos arquivos diretamente na sua lista de arquivos (com um filtro adequado para remover diretórios) e apenas excluir as últimas linhas em um editor de texto.

    
por 19.03.2012 / 22:07