Exibir um arquivo em um arquivo tar sem extraí-lo

16

Quero exibir o conteúdo do arquivo tarredado sem extraí-lo, Cenário: Eu tenho a.tar e, dentro, existe um arquivo chamado ./x/y.txt. Eu quero ver o conteúdo de y.txtsem realmente extrair o a.tar.

Ramji
fonte
Se você usa o Emacs, pode simplesmente abrir o tarball nele.
qudit
Er, para vê-lo, você precisa extraí-lo. Eu acho que o que você quer dizer é "sem gravá-lo em um arquivo"?
21815 Toby Speight

Respostas:

20

Provavelmente é uma opção específica do GNU, mas você pode usar -Oou --to-stdoutextrair arquivos para a saída padrão

$ tar -axf file.tgz foo/bar -O
fredtantini
fonte
Ah funciona, mas não consegui imprimir a saída em novas linhas. ex; tar -axf file.tar.gz --wildcards --no-anchored '*read_this_file*' --Oquando, por exemplo, muitos arquivos coincidem *read_this_file*. Tudo é impresso na mesma linha. Pelo man, eu encontrei --to-command. então Passar --to-command="echo '' && cat"é um pouco de magia negra, mas funciona: D
GabLeRoux 08/08
Apenas isso é necessário em resposta:$ tar -axf file.tgz foo/bar -O
user1742529 23/01
12

Isso imprime o conteúdo de ./x/y.txt de a.tar para STDOUT.

tar xfO a.tar ./x/y.txt

Toni
fonte
2
dica: é um "o" maiúsculo, não zero.
Hubert Grzeskowiak
4

Isso é simples como

less  a.tar:./x/y.txt

Este truque de mágica funciona se você tiver lesspipeinstalado e se a variável env LESSOPENestiver definida como o | /usr/bin/lesspipe.sh %sque é esperado se você tiver menos tubo instalado corretamente.

solstício
fonte
Esse é um roteiro incrível - mas há mais de um. Pelo que entendi, issolesspipe.sh provavelmente deve ser preferido.
mikeserv
Isso funcionará em tarballs compactados?
terdon
Deveria. Mas acabei de descobrir que não funciona no ubuntu. Vai saber. Eles quebraram ou removeram o recurso. Você ainda pode visualizar a lista de arquivo com menos, mas não o conteúdo do arquivo :-(
Solstício de
2

Ah, mas essa é uma pergunta sobre o conteúdo de um arquivo dentro de um tararquivo. E, na verdade, em alguns casos, isso não é tão difícil. O problema é que um tararquivo é apenas um arquivo de fluxo bloqueado - cada arquivo no arquivo morto é encontrado depois do arquivo anterior e cada arquivo obtém um cabeçalho de metadados com base em um formato especificado .

Com base nesse formato, eu escrevi uma vez shitar- que eram algumas linhas dde scripts de shell que podiam tarcriar um fluxo de dispositivos de bloco em tempo real. Baseado no mesmo, mais recentemente escrevi estas poucas linhas de código :

tar --no-recursion -c ./      |
{ printf \\0; tr -s \\0; }    |
cut -d '' -f-2,13             |
tr '\0\n' '\n\t'

... para separar um tararquivo em tempo real e realizar transformações embutidas em seus arquivos de texto componentes. Lá, os cutcampos apontam para os campos 1,2,13 de uma linha de entrada delimitada por NUL . Tais coisas são fáceis quando o tararquivo contém apenas arquivos de texto porque taros delimitadores de registro (como podem ocorrer uma vez a cada 512 bytes) podem ser reduzidos a um único NUL por e retirados - sem exigir que você conte as ocorrências como faz.

tarO formato do cabeçalho é assim:

field    offset   len
name     0        100
mode     100      8
uid      108      8
gid      116      8
size     124      12
mtime    136      12
chksum   148      8
typeflag 156      1
linkname 157      100
magic    257      6
version  263      2
uname    265      32
gname    297      32
devmajor 329      8
devminor 337      8
prefix   345      155

Entenda que existe uma inclinação acentuada entre a facilidade relativa de lidar tarcom operações simples com os aspectos muito mais complicados do formato de arquivo. Embora coisas simples - como agrupar um pequeno grupo de arquivos digitados de maneira homogênea ou até mesmo dividir um arquivo contendo apenas membros cujos tipos você possa prever - possam ser facilmente executadas com alguns tubos de shell, manipular com segurança membros arbitrários de arquivo não é um assunto trivial.

É especialmente difícil quando esses membros podem conter dados binários arbitrários - o que certamente impediria qualquer aplicação confiável de tr -s- e essa dificuldade só aumenta quando arquivos de vários tipos diferentes de regulares e / ou charsets diferentes do seu nativo são usados ​​e / ou o O arquivo original foi criado por uma implementação com idiossincrasias de aplicativo de formato com as quais você não está preparado para lidar. E isso toca apenas nos aspectos básicos e padronizados do tartipo de arquivo - adicione cabeçalhos estendidos e extensões de formato, arquivos esparsos e compactação e ... bem, boa sorte com eles.

De volta ao básico, no entanto, o tamanho padrão do registro para um tararquivo morto é de 20 blocos - ou 10240 bytes. Dado um arquivo bloqueado no tamanho de registro padrão e contendo apenas tipos de arquivo e ustarcabeçalhos padrão , você deve pular de cabeçalho para cabeçalho de membro fazendo leituras de acordo com o sizecampo de cabeçalho até encontrar um membro que corresponda ao de que você procura. Uma vez lá, leia em sizebytes o deslocamento começando no final do cabeçalho de membro do seu destino. E esse é o seu arquivo.

Pular os cabeçalhos não é muito fácil. Tipos diferentes terão ou não blocos de dados reais anexados que correspondem a size. Por exemplo, diretórios e links não conterão esse bloco de dados, apenas uma descrição de cabeçalho e, portanto, você deve estar preparado para verificar o tipo de arquivo do cabeçalho atual antes de determinar exatamente se deve aplicar o sizecampo à sua fórmula de ignorar ou não.

Além disso, os fatores de tamanho do registro - dependendo se os tamanhos dos membros do arquivo estão sincronizados ou não com o tamanho do registro padrão 10240 - , pode ou não haver um bloco 0 adicional anexado a cada um. E o tamanho do registro pode ser declarado no momento da criação do arquivo - e, portanto, pode nem ter 20 blocos, embora, por especificação, ele sempre deva ser bloqueado em unidades de 512 bytes:

  • ustar
    • O tarformato de intercâmbio; consulte a seção DESCRIÇÃO ESTENDIDA . O tamanho do bloco padrão para este formato para arquivos especiais de caracteres deve ser 10240 . As implementações devem oferecer suporte a todos os valores de tamanho de bloco menores ou iguais a 32256, múltiplos de 512 .

Portanto, se você estava trabalhando com um tararquivo que pode conter arquivos que podem conter dados binários arbitrários, é necessário pular o arquivo algoritmicamente e de acordo com o tipo de arquivo. A especificação diz:

  • O sizecampo é o tamanho do arquivo em octetos.
    • Se o typeflagcampo estiver definido para especificar um arquivo do tipo 1 (um link ) ou 2 (um link simbólico ) , o sizecampo será especificado como zero.
    • Se o typeflagcampo estiver definido para especificar um arquivo do tipo 5 ( diretório ) , o sizecampo deve ser interpretado conforme descrito na definição desse tipo de registro.
    • Nenhum registro lógico de dados é armazenado para os tipos 1 , 2 ou 5 .
    • Se o typeflagcampo estiver definido como 3 ( arquivo especial de caracteres ) , 4 ( arquivo especial de bloco ) ou 6 ( FIFO ) , o significado do sizecampo não será especificado por este volume do POSIX.1-2008 e nenhum registro lógico de dados deverá ser armazenado no meio.
    • Além disso, para o tipo 6 , o sizecampo deve ser ignorado durante a leitura.
  • Se o typeflagcampo estiver definido com qualquer outro valor, o número de registros lógicos gravados após o cabeçalho deve ser , ignorando qualquer fração no resultado da divisão.( (size+ 511 ) / 512 )

... e, é claro, considerando também o tamanho individual de cada cabeçalho - que é um bloco adicional por membro. Portanto, você pode pular a leitura e a leitura de cabeçalho para cabeçalho até chegar a um que corresponda ao cabeçalho que você procura, e nesse momento seria necessário verificar se o registro atual apenas descreve um link para o seu arquivo ou para o arquivo real . Isso é especialmente relevante porque quando o mesmo arquivo é adicionado a um arquivo múltiplo várias vezes, muitos tars incluem apenas cabeçalhos de link porque os dados do arquivo real já podem ser encontrados em outras partes do arquivo.

Depois de verificar que você precisará aplicar seus cálculos ao chksumcampo e verificar se o arquivo que você pensa que possui é realmente o arquivo que você deseja. tar's chksumé bastante simples though-:

  • cksum
    • O chksumcampo deve ser a representação IRV padrão ISO / IEC 646: 1991 do valor octal da soma simples de todos os octetos no registro lógico do cabeçalho. Cada octeto no cabeçalho deve ser tratado como um valor não assinado. Esses valores devem ser adicionados a um número inteiro não assinado, inicializado com zero, cuja precisão não é inferior a 17 bits. Ao calcular a soma de verificação, o chksumcampo é tratado como se fossem todos os caracteres <space> .

Claro, você não iria realmente tem que fazer nada disso, porque tarjá pode fazer isso - isso é o que ele faz - e por isso você deve, provavelmente, apenas usá-lo para pesquisar o arquivo e extraia o arquivo para você. Ao fazer isso, não fará nada muito diferente do que você faria se soubesse o que era, exceto que provavelmente o fará melhor e mais rápido porque esse é o seu trabalho. E de qualquer maneira, por que você deveria?

mikeserv
fonte
0

Você pode usar esta linha

tar -axf a.tar -O
tachomi
fonte
3
Isso mostrará qualquer arquivo existente no tar, não apenas y.txte não está claro pela pergunta do OP que esse é o único arquivo no tar.
Anthon