tar - extrair descartando a estrutura de diretórios

34

unzippossui uma opção bacana -j, na qual a estrutura de diretórios do archive é descartada e todos os arquivos são extraídos no mesmo diretório.

Existe uma maneira de fazer o tartrabalho da mesma maneira? Nada na página do manual parece indicar isso.

Então, existe uma alternativa, preferencialmente Software Livre, ferramenta que fará isso?

Benji XVI
fonte
Relacionado: Extraindo o Conteúdo do arquivo tar para o diretório pai .
G-Man diz 'Reinstate Monica'

Respostas:

79

O alcatrão GNU vive com característica, então naturalmente também tem algumas opções para isso.
http://www.gnu.org/software/tar/manual/html_node/transform.html

Se você apenas deseja remover alguns segmentos de caminho, então --strip-components=nou --strip=nfará o seguinte:

 tar xvzf tgz --strip=1

Mas também é possível regexcrever os arquivos a serem extraídos (os sinalizadores são --transformor --xforme aceitam ereg com o /xmodificador):

 tar xvzf tgz --xform='s#^[^/]+#.#x'
                 # or 's#^.+/##x' for discarding all paths

Para listar um alcatrão, você precisa da --show-transformedopção adicional :

 tar tvzf tgz --show-transformed --strip=1 --xform='s/abc/xyz/x'

Acredito que as opções de reescrita também funcionem para embalagem, não apenas para extração. Mas paxtem obviamente uma sintaxe melhor.

mario
fonte
4
Por que não s#.*/##?
L0b0
3
- strip acabou de fazer o meu dia. Obrigado!
SamStephens 2/12/12
--stripnão mencionado na página do manual os x tar, mas funciona mesmo assim, obrigado!
Slf 01/04
3
Muito melhor do que a resposta aceita.
Klaatu von Schlacker
existe alguma diferença entre --stripe --strip-components?
Joel Berkeley em
13

Você pode fazer isso facilmente em duas etapas. Adapte conforme necessário:

$ mkdir /tmp/dirtree
$ tar xfz /path/to/archive -C /tmp/dirtree
$ find /tmp/dirtree -type f -exec mv -i {} . \;
$ rm -rf /tmp/dirtree
MikeyB
fonte
é assim que eu faria (usando em find -exec mv -ivez de find | xargs) .... etapas simples que posso repetir em qualquer sistema sem ter que carregar um script para fazer isso por mim.
quack quixote
11
+1, tmpdir=$( mktemp -d )é útil ao criar diretórios temporários
sorki
8

pax pode fazer isso:

pax -v -r -s '/.*\///p' < archive.tar

ou

zcat archive.tar.gz | pax -v -r -s '/.*\///p'

Você pode verificar a operação de substituição de nome primeiro, omitindo a -ropção.

hfs
fonte
1

Uma solução possível que não requer a instalação de nada.

  1. use a tar tvfpara pegar todos os arquivos do tarball
  2. Extraia esses arquivos individualmente - faça a extração do tar para stdout e redirecione para $ filename

    tar -tvf $1 | grep -v "^d" | \
                  awk '{for(i=6;i<NF+1;i++) {printf "%s ",$i};print ""}' |\
                  while read filename
                  do
                     tar -O -xf $1 "$filename" > `basename "$filename"`
                  done
    

salve como extract.sh e execute como extract.sh myfile.tar. Ele também substituirá quaisquer nomes de arquivos duplicados encontrados nos diretórios extraídos do tarball.

DaveParillo
fonte
Na verdade, eu apenas testei em uma árvore de diretórios em casa e falha em arquivos que contêm espaços. Vou ver se não consigo postar uma atualização.
21430 DaveParillo
Corrigido, mas não é tão bonito quanto era.
21410 DaveParillo
-1
tar xf foo.tar.gz foo/path/to/file/bar.mp3 -O > bar.mp3

A -Oopção extrai um arquivo para o padrão e >redireciona essa saída para um arquivo. Então, no meu exemplo, estou extraindo foo.mp3 e redirecionando-o para bar.mp3. Os nomes dos arquivos são arbitrários.

Klaatu von Schlacker
fonte