Extraia vários arquivos .tar.gz com uma única chamada tar


35

Fiquei me perguntando se (e, claro, como) é possível dizer tarpara extrair vários arquivos em uma única execução.

Sou um usuário experiente do Unix há vários anos e, claro, sei que você pode usar uma forou mais findcoisas assim para chamar taruma vez para cada arquivo que deseja extrair, mas não consegui criar uma linha de comando que causasse a minha tarpara extrair dois arquivos .tar.gz de uma só vez. (E não, não há nada errado for, estou apenas perguntando se é possível ficar sem.)

Estou fazendo essa pergunta por curiosidade, talvez

  • há um garfo estranho em taralgum lugar que suporta isso
  • alguém sabe como usar o -Mparâmetro que tarme sugeriu quando tenteitar -zxv -f a.tgz -f b.tgz
  • somos todos cegos e é totalmente fácil de fazer - mas não consegui encontrar nenhuma dica na web que não utilizasse forou findou algo xargsparecido.

Por favor, não responda com tar -zxvf *.tar.gz(porque isso não funciona) e apenas responda com "não funciona" se tiver certeza absoluta sobre isso (e talvez também tenha uma boa explicação sobre o motivo ).

Edit: Fui apontado para uma resposta a esta pergunta no Stack Overflow, que diz detalhadamente que não é possível sem quebrar a tarsintaxe atual , mas não acho que isso seja verdade. Usar tar -zxv -f a.tgz -f b.tgzou tar -zxv --all-args-are-archives *.tar.gznão quebrar nenhuma sintaxe existente, imho.


Por curiosidade, qual é a situação que fez você começar a pensar em como evitar uma construção em loop?
Unclejamil 01/09/11

11
FYI: O tar GNU suporta arquivos tar de vários volumes com o -Mparâmetro
Steve-o

11
unclejamil: Estou escrevendo um HowTo e uma das etapas envolve descompactar vários arquivos compactados (.tar.bz2, .tar.gz, .zip). E como é um HowTo, fiquei pensando qual seria a linha de comando mais elegante para fazer isso. :)
scy

Respostas:


39

Isso é possível, a sintaxe é bem fácil:

$ cat *.tar | tar -xvf - -i

A opção -i ignora o EOF no final dos arquivos tar, na página de manual:

-i, --ignore-zeros
ignore blocks of zeros in archive (normally mean EOF)

11
Isso pareceu funcionar para mim. Comando exato que usei foi: cat *.tar.bz2 | tar -ixjv. Obrigado!
scy

11
<Para tgz> cat * .tgz | tar -xzvf - -i -C / destination / <ou> para o arquivo em * .tgz; do tar -xzvf $ arquivo -C / destino /; feito
Ferroao 6/12/17

27

para * .tar.gz

for file in *.tar.gz; do tar -zxf "$file"; done

para * .tar.bz2

for file in *.tar.bz2; do tar -jxf "$file"; done

para * .tar.xz

for file in *.tar.xz; do tar -Jxf "$file"; done

11
Corrija a formatação aqui, e isso será mais legível.
precisa saber é o seguinte

isso é ótimo. O formato também é ótimo, porque isso é como parece no terminal
smatthewenglish

11
Não esqueça de colocar aspas $filese seus arquivos tiverem nomes com espaços.
Alexander Revo

Isso realmente não responde à questão de saber se é possível extrair vários arquivos usando uma única invocação de tar. Além disso, o usuário diz que já está familiarizado com o uso de loops for para iterar sobre um conjunto de arquivos.
Kusalananda

2

Você precisa usar um loop. Não quebraria a tarsintaxe da linha de comando para permitir várias -fopções, mas exigiria a adição de código para processar vários arquivos em sequência, com todos os tipos de condições de borda (o que acontece se um arquivo no meio estiver malformado? Os arquivos podem usar diferentes mecanismos de compactação? Você também pode ter várias -Copções (opção tar GNU para extrair para um diretório específico)? E quanto a -K (opção tar tar GNU para iniciar com um determinado nome de membro)?…).

Uma possibilidade de evitar um forloop é instalar e ativar o AVFS , um sistema de arquivos FUSE que fornece acesso transparente aos arquivos. Cada arquivo /path/to/archivedobrado como um diretório ~/.avfs/path/to/archive#. Se você deseja combinar os arquivos com caracteres curinga, há um obstáculo em adicioná-lo #a uma correspondência curinga; isso pode ser feito no zsh.

mountavfs
cp -p ~/.avfs$PWD/{a,b}.tgz\#/* /destination
cp -p ~/.avfs/path/to/source/*.tgz(e\''REPLY=$REPLY\#'\')/* /destination

-1

find . -name "*.tar.gz" -exec tar xzf {} \;


o que isso faz?
Pierre.Vriens

11
Isso introduz um loop implícito chamando tar uma vez para cada arquivo encontrado, e o usuário diz que já sabe como fazer isso.
Kusalananda

desculpe, não li a pergunta com atenção, eu estava apenas procurando o caminho para extrair vários pacotes de alcatrão, leia a resposta acima e acho que usar a descoberta será mais fácil.
Zjengjie
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.