tar extrair no diretório com o mesmo nome base?

18

Eu tenho um arquivo zipado como myArchive123.tar.gz. Dentro, ele contém uma pasta comohelloWorld

Se eu extrair: tar -xf myArchive123.tar.gzrecebo a helloWorldpasta:

ls 
myArchive123.tar.gz
helloWorld 

Gostaria que a saída tivesse o mesmo nome que o nome do arquivo menos a extensão .tar.gz. Ou seja:

tar <magic paramaters> myArchive123.tar.gz 
ls 
 myArchive123.tar.gz
 myArchive123
cd myArchive123
ls 
  helloWorld

Isso pode ser feito?

  • Eu nunca sei o que há dentro do arquivo. Pode ser uma pasta, pode haver muitos arquivos.
  • Eu ficaria bem em usar outra ferramenta se o tar não puder fazer isso.
  • Eu ficaria bem com um formulário mais longo que pode ser transformado em um script

EDIT
Enquanto isso, hackeei um script que parece fazer o trabalho. (veja minha resposta postada abaixo). Se puder melhorar, sinta-se à vontade para postar comentários / respostas adicionais. O principal é que ele deve ser empacotado em uma linha como:

extract <file>
Leo Ufimtsev
fonte
11
O arquivo sempre contém exatamente uma pasta?
Mark Plotnick
Não sei o que há dentro dela no momento da extração. Isso também não deve depender do conteúdo do arquivo. Se for uma pasta, extraia a pasta lá. se for um arquivo, extraia todos os arquivos.
21815 Leo Ufimtsev
Nesse meio tempo, montei um script (veja abaixo). Só posso aceitar a resposta em 2 dias.
21815 Leo Ufimtsev
O arquivo conterá mais de uma pasta no nível superior?
precisa saber é o seguinte

Respostas:

10

Com gnu tar, você pode usar --xform(ou --transform) para anexar previamente /prefix/a cada nome de arquivo:

tar -xf myArchive.tar.gz --xform='s|^|myArchive/|S'

nota que não há é líder /em prefix/e as sedextremidades de expressão com Sa excluir alvos link simbólico de transformações de nome de arquivo.
Para testá-lo (execução a seco):

tar -tf myArchive.tar.gz --xform='s|^|myArchive/|S' --verbose --show-transformed-names

Para começar, aqui está um script muito simplista que você pode chamar como extract <file>:

STRIP = $ {1%. *} #Strip último sufixo
NAME = $ {STRIP% .tar} #strip .tar sufixo, se presente
comando tar -xf "$ 1" --xform = "s | ^ | $ NAME / | S" #run
don_crissti
fonte
Isso está próximo do que eu quero, exceto que eu gostaria de empacotá-lo em algo como: extract <file> #
Leo Ufimtsev #
Isso é buggy, ele pára no primeiro ponto. Por exemplo, eu tenho um arquivo como este: eclipse-SDK-4.5M6-linux-gtk-x86_64.tar.gz Espero uma saída sem o .tar.gz, mas obtenho eclipse-sdk-4
Leo Ufimtsev
No script acima, retiro a extensão e a removo ainda mais se encontrar um 'tar'.
21815 Leo Ufimtsev
Em geral, com muitos tipos de arquivos. Eu esperava uma linha rápida, pensei que talvez estivesse perdendo alguma bandeira de argumento. Mas parece que não há solução trivial para isso?
21815 Leo Ufimtsev
Coisa boa. Isso funciona e é mais curto que o script que escrevi. Agradável!
21815 Leo Ufimtsev
7

Bem, você pode fazê-lo em pelo menos duas etapas. Se você fez

mkdir <archive name>
tar -xf <archive name>.tar.gz --strip-components=1 -C <archive name>

isso cumpriria a tarefa, embora ainda possa haver uma resposta mais compacta.

Eric Renouf
fonte
3

Editar

A resposta aceita é mais curta que a abaixo. (faça a mesma coisa, mas menor é geralmente melhor).


Acabei me hackeando um script para a tarefa em questão. funciona com .tar .tar.gz e .gz

#!/bin/sh
#usage:
# nameOfScript myArchive.tar.gz
# nameOfScript myArchive.gz
# nameOfScript myArchive.tar
#
# Result:
# myArchive   //folder
fileName="${1%.*}" #extracted filename

#handle the case of archive.tar.gz
trailingExtension="${fileName##*.}"
if [ "$trailingExtension" == "tar" ]  
then
    fileName="${fileName%.*}"  #remove trailing  tar.
fi

mkdir "$fileName"
tar -xf "$1" --strip-components=0 -C "$fileName"

Uso:

   nameOfScript archive.tar.gz 
   ls 
    archive
   cd archive 
   ls 
    <archive content>

Observe que esta solução é capaz de pontos em um nome de arquivo. Por exemplo, Eclipse-4.5M-SDK.tar.gz.

Eu mantenho o script no meu repositório Git. Para a versão mais recente, consulte: https://github.com/LeoUfimtsev/ldts/blob/master/pathscripts/leo-tar-here

Leo Ufimtsev
fonte
2

Mais uma solução possível é usar a --transformopção:

tar -xzf ARCHIVE_NAME.tgz --transform="s/OLD_DIR_NAME/ARCHIVE_NAME/"

Com seus arquivos:

tar -xzf myArchive123.tar.gz --transform="s/helloWorld/myArchive123/"
svq
fonte
11
mas isto pressupõe que você sabe o que está dentro do arquivo
Leo Ufimtsev
por exemplo, como eu transformaria isso em um script de uma linha sem saber o que está dentro do arquivo?
21815 Leo Ufimtsev
Você está correto. É apenas uma solução possível, como eu escrevi aqui ...
svq
existe alguma diferença entre isso e --strip-compoments = 0 myArchive123?
21815 Leo Ufimtsev
11
E --strip-components=0simplesmente remove o primeiro nome do diretório do caminho e, com a -Copção, armazena arquivos desarquivados no novo diretório.
svq