Descompactando vários arquivos de uma vez


27

Eu tenho mais de 200 .ziparquivos em uma pasta. Eu não quero descomprimir aqueles um por um. Eu quero extrair aqueles usando um único comando ou script. Como fazer isso.

Respostas:


38

Se você realmente deseja descompactá-los em paralelo, você pode fazer

for i in *zip; do unzip "$i" & done

Isso, no entanto, iniciará processos N para arquivos N .zip e poderá ser muito pesado em seu sistema. Para uma abordagem mais controlada, iniciando apenas 10 processos paralelos por vez, tente o seguinte:

find . -name '*.zip' -print0 | xargs -0 -I {} -P 10 unzip {}

Para controlar o número de processos paralelos iniciados, mude -Ppara o que você quiser. Se você não deseja recursar em subdiretórios, faça o seguinte:

find . -maxdepth 1 -name '*.zip' -print0 | xargs -0 -I {} -P 10 unzip {}

Como alternativa, você pode instalar o GNU paralelo, como sugerido por @OleTange nos comentários e executar

parallel unzip ::: *zip

3
Rodar em paralelo é uma boa ideia, mas a E / S de disco não será o principal gargalo?
Paddy Landau

1
@PaddyLandau não tenho certeza, eu teria que verificar. Isso dependerá da velocidade do algoritmo de descompressão versus a velocidade do disco que eu imagino.
terdon

Use -execou em -execdirvez de canalizar para xargs. Além de ser mais simples de entender, também é menos propenso a erros e utiliza menos recursos do sistema. find . -name '*.zip' -exec unzip {} ';'(Você deve citar o ponto e vírgula.)
Paddy Landau

@PaddyLandau, a única razão pela qual estou usando o xargs é executar as coisas em paralelo, como o OP pediu. -exec \;(você pode escapar do ponto-e-vírgula, sem necessidade de aspas), executará cada comando sequencialmente. -exec +é melhor, mas não vai funcionar aqui, pois não é assim que unzipfunciona.
terdon

Eu acho que entendemos o OP de maneira diferente. Você o lê como querendo em paralelo, enquanto eu o entendia como significando um único comando em vez de vários comandos. Bem, ele tem ambos os métodos agora :)
Paddy Landau

17

O comando paralelo GNU é adequado para esse tipo de coisa. Depois de:

$ sudo apt-get install parallel

Então

ls *.zip | parallel unzip

Isso usará quantos núcleos você tiver, mantendo cada núcleo ocupado com um descompactação, até que tudo esteja pronto.


É uma idéia melhor usar echo *.zippara evitar que um possível alias ls oculte informações extras. No entanto, isso tem o mesmo problema que a resposta do @ Guru; ele quebra nos nomes de arquivos que contêm espaços em branco.
precisa saber é o seguinte

1
@ nyuszika7h Em contraste com xargsGNU Parallel não não quebrar em nomes de arquivos que contenham espaço / guia / quote. Somente se os nomes dos arquivos contiverem novas linhas, você terá que tomar cuidado extra. Por exemplo, usando:parallel unzip ::: *.zip
Ole Tange

@ nyuszika7h - Estas são boas razões para evitar tanto aliasing comandos padrão, e colocando espaços em nomes de arquivos.
Wayne Conrad

@ nyuszika7h usando echoé tão ruim quanto usar ls. Globbing e um loop while são os mais seguros.
terdon

1
@NateEldredge Embora essa chance tenha sido maior no tempo em que os sistemas tinham apenas um disco magnético, hoje em dia com RAIDs com vários eixos e disco flash, essa chance é menor. É claro que a melhor coisa a fazer é medir e ver como o sistema se comporta. Recentemente, usei um RAID de 40 eixos em que o paralelismo ideal para processos com fome de E / S era 10: não deu uma velocidade de 10x - apenas 6x, mas menos de 10 processos deram menos de 6x.
precisa

12

Você pode usar o seguinte comando:

Primeiro mude o diretório no terminal para o diretório que contém os arquivos .zip:

cd /path

Em seguida, execute este comando para descompactar todos os arquivos .zip:

for z in *.zip; do unzip "$z"; done

10

Se você possui muitos .ziparquivos na sua pasta e deseja descompactá-los, abra o terminal e vá para a sua pasta usando:

cd <path_to_folder>

Agora use este comando para descompactar todo o seu .ziparquivo:

ls *.zip | xargs -n1 unzip

3
Isso falhará se algum dos nomes de arquivo contiver espaço em branco.
terdon

1
sim você está correto.
g_p 8/03/2014

É uma idéia melhor usar echo *.zippara evitar que um possível lsalias oculte informações extras, mas isso ainda não resolve o problema de espaço em branco.
precisa saber é o seguinte

1
@OleTange Caso você não tenha notado, eu disse que ainda falha nos nomes dos arquivos com espaços em branco.
precisa saber é o seguinte

1
Nunca dependa da saída de lspara scripts, pois sua saída não está bem definida entre as versões. Em vez disso, observe a resposta do @terdon, pois resolve todos os problemas dessa solução.
Paddy Landau

6

Você pode usar o find com -execassim,

find . -name "*.zip" -exec unzip {} \;

Isso vai funcionar se o arquivo tem um espaço no nome.


3

Um método não terminal.

Basta selecionar os arquivos zip, clicar com o botão direito do mouse em um e escolher extract here. Você pode selecionar todos ou apenas um número de arquivos zip por vez.


1

unzip \*.zip ou unzip '*.zip'

O óbvio unzip *.zipnão funciona, porque o shell o expande unzip foo.zip bar.zip ...e unzipinterpreta o primeiro nome do arquivo como o arquivo zip e os seguintes nomes de arquivos como arquivos a serem extraídos desse arquivo zip.

No entanto, unzipé um pouco incomum entre os comandos do Unix, pois ele faz suas próprias expansões globais. Se o *arquivo não for expandido pelo shell, descompacte-o e interprete todos os nomes de arquivos resultantes como arquivos zip a serem processados. Portanto, neste caso especial, pode-se fugir sem um forloop ou algo xargsparecido.

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.