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.

assustador
fonte
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)
polinomial
fonte
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
Ratnesh
fonte
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
Gilles 'SO- parar de ser mau'
fonte
-1

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

zjengjie
fonte
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