Transformar os caminhos de um arquivo tar sem extraí-lo

9

O GNU tar(1) tem uma opção simples chamada --transform . Na página do manual:

--transform, --xform EXPRESSION
use sed replace EXPRESSION to transform file names

Isso permite a transformação de nomes de caminho enquanto o arquivo está sendo extraído, para que você possa controlar onde e como ele será extraído.

Minha pergunta é: existe uma maneira de realizar uma transformação semelhante in situ ; ou seja, sem extrair o arquivo?

Exemplo

[user@host]$ tar tf test.tar
./foo/blah  ./foo/bleh
[user@host]$ some_deep_magic 's/foo/bar/' test.tar
[user@host]$ tar tf test.tar
./bar/blah  ./bar/bleh

Caso de uso

Estou distribuindo um arquivo tar para usuários finais sem noção e gostaria de extrair o caminho correto sem a interferência de mim. Eu estou tentando evitar a solução trivial de extrair o arquivo, renomeando os diretórios e reembalando como o arquivo é largamente.

    
por Joseph R. 09.01.2014 / 22:55

1 resposta

3

Você pode montar o arquivo com o archivemount ou o mountavfs e recriá-lo novamente

archivemount tarfile.tar /mnt
cd /mnt
tar cf /tmp/tarfile.tar --transform 's/foo/bar/' .

as operações de gravação no sistema de arquivos de arquivos farão uma reescrita completa no umount, então não pareça uma boa opção para arquivos grandes.

EDITAR

Eu não sei detalhes de implementação, mas parece que estamos salvando os arquivos de gravação na etapa do sistema de arquivos.

Apenas teste para resolver dudes (em um tar do meu / usr)

#!/bin/bash

# try to avoid slab cache issues 
cat /tmp/usr.tar > /dev/null

T="$(date +%s)"
tar xf /tmp/usr.tar
tar cf usr.tar usr --transform 's/usr/foo/'
T="$(($(date +%s)-T))"
echo "Tar/Untar seconds: ${T}"

T="$(date +%s)"
archivemount -o readonly -o nobackup /tmp/usr.tar /mnt
tar cf usr.tar /mnt  --transform 's/usr/foo/'
umount /mnt
T="$(($(date +%s)-T))"
echo "Archivemount seconds: ${T}"

T="$(date +%s)"
mountavfs
cd '/root/.avfs/tmp/usr.tar#'
tar cf /tmp/test/usr.tar   --transform 's/usr/foo/' .
T="$(($(date +%s)-T))"
echo "Avfs seconds: ${T}"

Saída:

Tar/Untar seconds: 480
Archivemount seconds:  failure, a lot of read errors.
Avfs seconds: 217

Então Avfs vence! .

    
por 10.01.2014 / 01:23

Tags