Adicionar / atualizar um arquivo em um arquivo tar.gz existente?

73

Existe uma maneira de adicionar / atualizar um arquivo em um arquivo tar.gz? Basicamente, eu tenho um arquivo que contém um arquivo em /data/data/com.myapp.backup/./files/settings.txte gostaria de extrair esse arquivo do arquivo (já concluído) e enviá-lo de volta ao arquivo assim que a edição for concluída. Como posso fazer isso? É problemático por causa do .caminho?

Naftuli Kay
fonte
2
+1. Isso tornaria o trabalho no OS X tão fácil. Atualmente, eu tenho que limpar manualmente um diretório com todos os arquivos ocultos .DS_Storee, em seguida, refazer o tar do diretório.

Respostas:

15

O formato do arquivo tar é apenas uma série de arquivos concatenados, juntamente com alguns cabeçalhos. Não é um trabalho muito complicado separá-lo, colocar seu conteúdo e juntá-lo novamente. Dito isto, Jander descreveu como o tar como um programa não possui as funções de utilidade para fazer isso e existem complicações adicionais com a compactação, o que deve ocorrer antes e depois da alteração.

Existem, no entanto, ferramentas para o trabalho! Existem pelo menos dois sistemas disponíveis, que permitirão que você faça uma montagem de loopback de um arquivo tar compactado em uma pasta e faça as alterações no sistema de arquivos. Quando terminar, desmonte a pasta e seu arquivo compactado está pronto para rolar.

A primeira opção seria o projeto de arquivo morto para o FUSE . Aqui está um tutorial sobre isso . Provavelmente, seu sistema já possui o FUSE e, caso contrário, sua distribuição deve ter uma opção para ele.

A outra opção é tarfs . É mais simples de usar , mas ouvi dizer que ele tem alguns problemas com a corrupção de arquivos bzip2, para que você possa testar isso muito bem primeiro.

Caleb
fonte
11
Eu uso o AVFS , que é empacotado no Ubuntu e Debian. Você sabe como o archivemount e o tarfs se comparam ao AVFS?
Gilles
Honestamente, não, não, embora esteja curioso para analisar o AVFS agora que você mencionou a alternativa. Eu usei o archivemount e o tarfs, mas foi por um longo tempo que o projeto foi desativado e não sei seu estado atual. Eu meio que decidi a partir dessa experiência que a idéia estava errada conceitualmente, mesmo que a implementação funcionasse perfeitamente.
Caleb
Dei uma olhada em como o archivemount funciona. Ele não modifica o arquivo .tar.gz existente, mas quando você desmonta, renomeia o original e cria um novo arquivo tar em seu lugar. Se você está procurando uma boa experiência do usuário, é ótimo, mas se você deseja evitar a reescrita de todo o arquivo por motivos de eficiência, isso não ajudará.
Jander
@ Jander Isso é para apontar isso. Tenho certeza de que se aplica a todas as opções de montagem de arquivos compactados. O problema é que as partes individuais do arquivo não são compactadas, os cabeçalhos internos do arquivo geral e tudo são compactados e, para que outras coisas sejam extraídas, o esperado é que o gzip seja executado em todo o conjunto de dados. Não há como injetar algo no meio disso sem extraí-lo e executar novamente a compactação e reescrever o arquivo de dados inteiro. Daí o meu comentário anterior sobre ser a solução errada conceitualmente . Arquivos são arquivos.
Caleb
43

Para extrair seu arquivo do seu arquivo, você pode usá-lo tar xzf archive.tar.gz my/path/to/file.txt. Observe que os diretórios no caminho do arquivo também serão criados. Use tar t(ie tar tzf archive.tar.gz) para listar os arquivos no arquivo morto.

tarnão suporta atualização "in-loco" de arquivos. No entanto, você pode adicionar arquivos ao final de um arquivo morto, mesmo se eles tiverem o mesmo caminho que um arquivo que já está no arquivo morto. Nesse caso, as duas cópias do arquivo estarão no arquivo morto e o arquivo adicionado posteriormente substituirá o anterior. O comando a ser usado para isso é tar r(ou tar uapenas para adicionar arquivos mais recentes que o archive) é o comando a ser usado. O .caminho não deve ser um problema.

Existe um problema: você não pode adicionar a um arquivo compactado. Então você teria que fazer:

gunzip archive.tar.gz
tar rf archive.tar data/data/com.myapp.backup/./files/settings.txt
gzip archive.tar

O que provavelmente não é o que você deseja ouvir, pois significa reescrever o arquivo inteiro duas vezes. Se não for um arquivo muito grande, talvez seja melhor descompactar a coisa toda e depois refazê-la novamente após a edição. Como alternativa, você pode usar um arquivo não compactado.

Jander
fonte
Esta resposta está correta apenas na medida em que lida com o tarprograma padrão . Tar como um formato de arquivo é realmente muito acessível. Você pode escrever facilmente um script para atualizar o conteúdo, mas existem outras ferramentas que já fazem isso .
Caleb
23
Você também pode fazer isso da maneira Unix:gzip -dc archive.tar.gz | tar -r data/data/com.myapp.backup/./files/settings.txt | gzip >archive_new.tar.gz
Simon Richter
2
No IIRC, você pode simplesmente concatenar dois arquivos compactados em gzip. O resultado é um arquivo compactado com gzip maior que contém os dois arquivos não compactados concatenados.
FUZxxl 21/03
Depois de descompactar o arquivo, não é possível usar o sinalizador --update?
Pietro #:
@FUZxxl +1 para mentionning concatenação gzip
Johan Boulé
9

O Tar foi originalmente projetado para ser usado em fitas, portanto, "substituir" os arquivos não está realmente no design. No entanto, você pode usar --delete para excluir o arquivo do tar original e, em seguida, -u para atualizar o tar e adicionar novamente o arquivo. Pode demorar um pouco, pois o tar precisa reorganizar o arquivo internamente.

rleibman
fonte
Bem-vindo ao StackExchange! Sua resposta contém apenas uma sugestão já feita em outra resposta . Leia as outras respostas a uma pergunta antes de responder, para evitar a criação de duplicatas.
JigglyNaga 29/07/16
11
Eu editei minha resposta um pouco. Eu não acho que a outra resposta mencione --delete
rleibman
-5

no meu Linux x86_64 GNU / Linux para executar essa operação, uso simplesmente o seguinte comando:

tar cvfpz /path/archive.tar -T list.txt

Este comando causa a criação de um arquivo compactado /pathusando uma lista de arquivos incluídos no list.txtarquivo.

user64312
fonte
6
Isso substitui um arquivo existente /path/archive.tar, em vez de adicionar / atualizar esse arquivo.
Anthon