Como combinar / mesclar arquivos zip?

21

Nos últimos meses, copiei várias pastas de dados para compactar arquivos em intervalos semanais. Agora eu gostaria de combinar esses arquivos zip em um arquivo zip, porque a maioria do conteúdo dos arquivos zip existentes são apenas versões diferentes dos mesmos arquivos de dados.

Portanto, se um arquivo aparecer em mais de um dos arquivos zip existentes, eu gostaria que a versão mais recente estivesse no novo arquivo zip que está sendo criado. Obviamente, se um arquivo aparecer em apenas um arquivo zip existente, também o desejo no arquivo zip final.

Estou tentando evitar descompactá-los um a um em uma pasta de trabalho, substituindo dados de arquivos zip mais antigos por dados de arquivos zip mais recentes e depois compactando tudo em um novo arquivo zip.

Pelo que entendi, o pkzip combinaria os arquivos zip eles mesmos, mas existe um método gratuito confiável e rápido que alguém possa me contar?

CChriss
fonte
1
zipmerge para a vitória
código Bling

Respostas:

7

você não vai gostar, mas: descompactar tudo em uma pasta de trabalho na ordem certa e, em seguida, compactar o resultado é a maneira mais eficaz.

caso contrário, você acabará com muitos ciclos de CPU desperdiçados:

  • suponha que seu resultado vá para 'first.zip'
  • todo arquivo de '2.zip', '3.zip' etc deve ser descompactado e depois compactado novamente em 'first.zip'
  • em '2.zip' existe um arquivo 'foobar.txt' e em '3.zip' existe outro arquivo 'foobar.txt'. mesclá-lo da maneira que você deseja mesclar leva a 'comprimir X vezes'
  • o toc de um .zip está no final do arquivo: você adiciona mais conteúdo (no meio do
    arquivo .zip, atualizando um arquivo no meio) e o arquivo inteiro deve ser reescrito

então, imho basta usar wiseley ' unzip ':

% mkdir all
% for x in *.zip ; do unzip -d all -o -u $x ; done
% zip -r all.zip all

a ordem do descompactação é importante, não sei o padrão dos seus nomes de zip, mas extrairia primeiro o arquivo zip mais recente, a opção '-u' de descompactar substitui apenas arquivos se forem mais novos ou cria arquivos se não forem já está lá. como resultado, você descompactará apenas os arquivos mais recentes e compactará o resultado apenas uma vez.

akira
fonte
Isso pode ser mais eficaz da perspectiva do usuário - mas não é preciso. A tabela de arquivos em um zip está de fato no final, mas você pode gravar arquivos arbitrariamente no final de qualquer zip e, em seguida, escrever uma nova tabela de arquivos. O último registro sempre vence. Aqueles com um pouco de familiaridade com scripts ou programação poderiam executar todo esse processo sem descompactar ou compactar arquivos, apenas movendo os blocos binários e atualizando a tabela zip.
caesay
Na verdade, você pode concatenar todos os zips em um único arquivo (na ordem que desejar) e depois escrever um novo registro no final para incluir apenas as versões mais recentes. Isto tem a vantagem adicional de que o zip ainda contém todas as versões anteriores de arquivos que podem ser recuperados se nessesary
caesay
"todo arquivo de '2.zip', '3.zip' etc deve ser descompactado e depois compactado novamente em 'first.zip'" não está correto. O zipmergeutilitário mescla arquivos ZIP sem descompactar e recompactar, por exemplo.
ZachB
Eu usei unzipping/ zippinge não uncompress / decompress. Sim, obviamente, é possível pegar uma entrada de 2.zip(o blob compactado) e transferi-la para first.zipe, portanto, nenhuma "compressão" deve ocorrer. Mas você precisa extrair o blob de 2.zip, pesquisar a existência no sumário first.zip, se ele substituir a entrada existente (o que significa que você deve reescrever o arquivo inteiro basicamente) ou anexá-lo no final - e depois disso você precisará anexe o toc do zip. Eu não vejo como zipmergepode atingir a fusão de zip-entradas de uma maneira diferente (compressão de lado)
akira
-1 porque existem maneiras muito mais eficientes de executar essa tarefa, e nenhuma das justificativas para isso ser "a maneira mais eficaz" faz o menor sentido. every file [...] has to be unzipped and then zipped again- não, é isso que sua solução faz. in '2.zip' exists a file 'foobar.txt' and in '3.zip' exists another file 'foobar.txt'. merging it the way you want to merge it leads to 'compress it X times'- não, não faz. Por quê? you add more content [...] and the whole file has to be rewritten- não, você escreve a saída em uma passagem. Por que alguém votou nisso?
benrg 9/10
4

Basta usar a opção -g do ZIP, onde você pode anexar qualquer número de arquivos ZIP em um (sem extrair os antigos). Isso economizará tempo significativo.

Também dê uma olhada no zipmerge

Christos
fonte
4
-gadiciona arquivos a um zip existente. não os mescla. por exemplo: zip -g result.zip other.zipadicionará o arquivo other.zipem result.zip . --grow Aumente (anexe ao) o arquivo zip especificado, em vez de criar um novo. Se essa operação falhar, o zip tentará restaurar o arquivo morto para seu estado original. Se a restauração falhar, o arquivo morto pode ficar corrompido. Esta opção é ignorada quando não há arquivo morto ou quando pelo menos um membro do arquivo deve ser atualizado ou excluído
akira
2

https://linux.die.net/man/1/zipmerge :

O zipmerge mescla os arquivos zip de origem source-zipno arquivo zip de destino target-zip. Por padrão, os arquivos nos arquivos zip de origem substituem os arquivos existentes com o mesmo nome no arquivo zip de destino.

imz - Ivan Zakharyaschev
fonte
1

Eu estava pensando que você poderia criar um script dos arquivos sendo extraídos em um diretório temporário.

Há um problema com esta linha de comando. Não consegui encontrar uma maneira de ordenar o descompactação de arquivos, portanto um arquivo mais antigo pode substituir um arquivo mais recente. Esse problema pode ser solucionado usando um descompactador, que possui uma opção de linha de comando para substituir somente se for mais recente. Eu uso principalmente o 7-Zip, que não tem essa opção de linha de comando.

Além disso, esse comando precisa que todos os arquivos zip estejam no mesmo diretório. Não é um problema se todos os zips tiverem nomes exclusivos. Dito isto, o comando pode ser alterado para se adequar à sua situação.

for /f %f in ('dir /b *.zip') do "c:\program files\7-zip\7z" x %f -oc:\testdir -r -aoa

Para alterar isso para usar outro programa de descompactação, substitua "c:\program files\7-zip\7z" x %f -oc:\testdir -r -aoapor qualquer comando que você executaria em cada arquivo. Use %fcomo espaço reservado para o nome do arquivo que você deseja descompactar.

Tentei procurar um aplicativo polido, gratuito ou não, e realmente não encontrei um.

Espero que isso lhe dê um bom começo e o WinZip ou algo semelhante possa resolver o problema de substituição.

Boa sorte.

Scott McClenning
fonte
0

Se bem me lembro, o pkzip era um programa de linha de comando.

Ainda existe uma versão do ZIP na linha de comando que afirma ser compatível com o pkzip.

Chama -se Info-ZIP e deve haver uma versão para o seu sistema operacional.

pavium
fonte
Ele tem a funcionalidade que estou perguntando? Não consigo encontrar onde ele lista essa capacidade.
CChriss
1
O conjunto Info-Zip torna os arquivos compatíveis com o PKZip, mas os programas em si são diferentes e não parecem incluir uma opção de mesclagem.
CarlF
OK, desculpe, eu pude compilar e executar o Info-Zip em uma estação de trabalho Apollo em DOMAIN / OS há muitos anos. Lembro que ele forneceu recursos diferentes no DOS / VMS / Unix e em alguns outros, mesmo assim. Suponho que possa ter evoluído ainda mais.
pavium
0

Procure a linha de comando winzip na rede. O Winzip possui várias versões das ferramentas de linha de comando para se adequar à versão do winzip que você possa ter instalado. A ferramenta de linha de comando WZZIP possui uma opção -f "freshen" que compactará arquivos mais recentes apenas aqueles que correspondem ao nome de um arquivo no arquivo zip de saída de soma.

Use o WZunzip agrupado em uma instrução FOR como mostrado acima para descompactar um arquivo em um diretório e depois o WZzip -f para adicionar esses arquivos a um arquivo zip de soma de saída. Em seguida, o loop FOR se repete para trabalhar no próximo arquivo de entrada a ser gerado no único arquivo de saída somatório. A ordem dos arquivos de entrada não importa, pois o WZzip -f só será adicionado ao arquivo de saída se os dados de entrada forem mais novos do que os que já estão no arquivo de saída. Todos os arquivos que não existem no arquivo de saída também serão adicionados. Você pode descompactar o resultado em uma pasta e depois compactá-lo novamente para obter um arquivo de resultados compactado com eficiência. Você pode fazer isso automaticamente após o loop FOR no final do arquivo em lotes.

eewiz
fonte