Extrair apenas um arquivo específico de um arquivo compactado zipado para um determinado diretório

151

Preciso extrair um único arquivo de um arquivo ZIP para o qual conheço o caminho. Existe um comando como o seguinte:

unzip -d . myarchive.zip path/to/zipped/file.txt

Infelizmente, o comando acima extrai e recria todo o caminho para o arquivo em ./path/to/zipped/file.txt. Existe uma maneira de eu simplesmente puxar o arquivo para um diretório especificado?

Naftuli Kay
fonte

Respostas:

130

Você pode extrair apenas o texto para a saída padrão com a -popção:

unzip -p myarchive.zip path/to/zipped/file.txt >file.txt

Isso não extrairá os metadados (data, permissões, ...), apenas o conteúdo do arquivo. Esse é o preço a pagar pela conveniência de não precisar mover o arquivo posteriormente.

Como alternativa, monte o arquivo morto como um diretório e apenas copie o arquivo. Com o AVFS :

mountavfs
cp -p ~/.avfs"$PWD/myarchive.zip#"/path/to/zipped/file.txt .

Ou com zip-fusível :

mkdir myarchive.d
fuse-zip myarchive.zip myarchive.d
cp -p myarchive.d/path/to/zipped/file.txt .
fusermount -u myarchive.d; rmdir myarchive.d
Gilles
fonte
2
@TK Kocheran: Por que você não apenas testa? Eu testei o primeiro comando e funcionou.
usuário desconhecido
1
@TKKocheran: os arquivos jar são compactados, então os métodos descompactar e fuse-zip obviamente funcionarão. O método AVFS também funciona, porque o AVFS adivinha o formato com base nos nomes dos arquivos e conhece .jar; se o seu arquivo tiver um nome diferente, você pode precisar informar ao AVFS para usar seu manipulador de zip, por exemplo ~/.avfs$PWD/foo.apk#uzip/META-INF.
Gilles
1
na verdade, eu quis dizer extrair um arquivo JAR / binário de um arquivo ZIP. Ainda não tive a chance de testá-lo. Você vê algum problema ao usar o primeiro comando acima para extrair arquivos binários?
Naftuli Kay
2
@TKKocheran: Não há problema, -pextrai o arquivo como está ( -cfaz a conversão de texto).
Gilles
2
Eu acho que a resposta do @Myles é mais elegante, porque não requer redirecionamento de saída e preserva os atributos do arquivo.
Gdvdijk
152
unzip -j "myarchive.zip" "in/archive/file.txt" -d "/path/to/unzip/to"

Digite o caminho completo para o arquivo compactado, não apenas o nome do arquivo. Certifique-se de manter a estrutura como vista de dentro do arquivo zip.

Isto irá extrair o arquivo único file.txtem myarchive.zipque /path/to/unzip/to/file.txt.

sMyles
fonte
18
Essa é a melhor resposta.
Redeborn
1
Ele não lida com o caso em que você deseja que o nome do arquivo gerado seja diferente.
Oleg Vaskevich 27/10/2014
6
o parâmetro "-j": caminhos indesejados. A estrutura de diretórios do arquivo morto não é recriada; todos os arquivos são depositados no diretório de extração (por padrão, o atual). o parâmetro "-d": extrai arquivos para o exdir
e1i45
1
@OlegVaskevich, a questão não solicitar nome de arquivo alvo para ser diferente
Tapemaster
Sim, eu sei. Ainda com votos positivos. :)
Oleg Vaskevich
25

Versão mais simples:

unzip ARCHIVE_NAME PATH_OF_FILE_INSIDE_ARCHIVE

Isso será recriado PATH_OF_FILE_INSIDE_ARCHIVEno diretório atual, mas apenas extrairá o arquivo especificado.

Para listar todos os arquivos em um arquivo Zip:

unzip -l ARCHIVE_NAME
Taukir
fonte
2
Muito mais simples que a resposta aceita.
FractalSpace
Na verdade, funcionou bem e é waaaay mais simples
Mahmoud Ali
2

No macOS , que por padrão usa o Info-Zip

Primeiro, liste os arquivos para encontrar o que deseja

unzip -l my.zip

Em seguida, forneça uma lista de arquivos a serem extraídos do arquivo

unzip my.zip annoying/path/to/file

Combine com -p para stdout

unzip -p my.zip annoying/path/to/file >./file
Cameron Lowell Palmer
fonte
1
Não entendo por que as pessoas votam sem motivo óbvio. Esta é uma resposta correta (e não apenas para o macOS) #
1560
@FractalSpace Patentemente não, faz o oposto do que o OP quer.
Konrad Rudolph
A chave é obter um arquivo individual. A saída para stdout e o redirecionamento usando o sinalizador -p é trivial, mas eu o adicionei explicitamente
Cameron Lowell Palmer
2

uso simples:

unzip zipfile.zip path/inside/zip/file.txt

e inflará o arquivo.

$ unzip -l ./../html.zip | grep wp-config

     3328  07-22-2019 15:10   html/wp-config.php

     2898  01-07-2019 23:30   html/wp-config-sample.php

$ unzip ./../html.zip html/wp-config.php

     Archive:  ./../html.zip
     inflating: html/wp-config.php

$ ls -lrth

     total 4.0K
     drwxr-sr-x 2 apache apache 4.0K Jul 26 14:41 html

$ ls -lrth html/*

     total 4.0K
     -rw-rw-rw- 1 apache apache 3.3K Jul 22 15:10 wp-config.php
Alejandro Cesar Bravo Anaya
fonte
Também pode adicionar o -d outpathargumento para especificar onde o arquivo será colocado.
Efren 18/09
E o -jargumento para evitar os caminhos compactados
Efren