Descomprimir múltiples archivos a la vez


27

Tengo más de 200 .ziparchivos en una carpeta. No quiero descomprimirlos uno por uno. Quiero extraer aquellos usando un solo comando o script Como hacer eso.

Respuestas:


38

Si realmente quieres descomprimirlos en paralelo, puedes hacer

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

Sin embargo, eso lanzará N procesos para archivos N .zip y podría ser muy pesado en su sistema. Para un enfoque más controlado, lanzando solo 10 procesos paralelos a la vez, intente esto:

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

Para controlar la cantidad de procesos paralelos iniciados, cambie -Pa lo que desee. Si no desea recurse a subdirectorios, haga esto en su lugar:

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

Alternativamente, puede instalar GNU paralelo como lo sugiere @OleTange en los comentarios y ejecutar

parallel unzip ::: *zip

3
Ejecutar en paralelo es una buena idea, pero ¿no será la E / S de disco el principal cuello de botella?
Paddy Landau

1
@ PaddyLandau no estoy seguro, tendría que comprobarlo. Dependerá de la velocidad del algoritmo de descompresión frente a la velocidad del disco que imagino.
terdon

Use -execo en -execdirlugar de tubería a xargs. No solo es más fácil de entender, sino que también es menos propenso a errores y utiliza menos recursos del sistema. find . -name '*.zip' -exec unzip {} ';'(Debe citar el punto y coma.)
Paddy Landau

@PaddyLandau, la única razón por la que me dirijo a xargs es para ejecutar las cosas en paralelo como lo solicitó el OP. -exec \;(puede escapar del punto y coma, sin necesidad de comillas), ejecutará cada comando secuencialmente. -exec +es mejor, pero no funcionará aquí, ya que no es así unzip.
terdon

Creo que hemos entendido el OP de manera diferente. Lo lees como queriendo en paralelo, mientras que lo entendí como un solo comando en lugar de múltiples comandos. Bueno, él tiene ambos métodos ahora :)
Paddy Landau

17

El comando paralelo GNU es muy adecuado para este tipo de cosas. Después:

$ sudo apt-get install parallel

Luego

ls *.zip | parallel unzip

Esto usará todos los núcleos que tenga, manteniendo cada núcleo ocupado con un descomprimir, hasta que todos estén listos.


Es una mejor idea usar echo *.zipen su lugar para evitar que un posible alias ls ingrese información adicional. Sin embargo, esto tiene el mismo problema que la respuesta de @ Guru, se rompe en los nombres de archivo que contienen espacios en blanco.
nyuszika7h

1
@ nyuszika7h A diferencia de xargsGNU Parallel no se rompe en los nombres de archivo que contienen espacios / tabuladores / comillas. Solo si los nombres de los archivos contienen nuevas líneas, deberá tener especial cuidado. Por ejemplo, usando:parallel unzip ::: *.zip
Ole Tange

@ nyuszika7h - Estas son buenas razones para evitar tanto la aparición de artefactos comandos estándar, y espacios que ponen en los nombres de archivo.
Wayne Conrad

@ nyuszika7h usar echoes tan malo como usar ls. Globbing y un bucle while es lo más seguro.
terdon

1
@NateEldredge Si bien esa posibilidad era mayor en la época en que los sistemas tenían solo un disco magnético, en estos días con RAID con múltiples husillos y disco flash, esa posibilidad es menor. Lo mejor que puede hacer es, por supuesto, medir y ver cómo se comporta su sistema. Recientemente utilicé un RAID de 40 husos donde el paralelismo óptimo para los procesos hambrientos de E / S era 10: no daba una aceleración de 10x, solo 6x, pero menos de 10 procesos dieron menos de 6x.
Ole Tange

12

Puede usar el siguiente comando:

Primero cambie el directorio en la terminal al directorio que contiene archivos .zip:

cd /path

Luego ejecute este comando para descomprimir todos los archivos .zip:

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

10

Si tienes muchos .zip archivos en su carpeta y desea descomprimirlos, abra el terminal y vaya a su carpeta usando:

cd <path_to_folder>

Ahora use este comando para descomprimir todo su .ziparchivo:

ls *.zip | xargs -n1 unzip

3
Esto fallará si alguno de los nombres de archivo contiene espacios en blanco.
terdon

1
sí, estás en lo correcto.
g_p

Es mejor usarlo echo *.zippara evitar que un posible lsalias filtre información adicional, sin embargo, eso aún no soluciona el problema del espacio en blanco.
nyuszika7h

1
@OleTange En caso de que no lo hayas notado, dije que todavía falla en los nombres de archivos con espacios en blanco.
nyuszika7h

1
Nunca dependa de la salida de los lsscripts, ya que su salida no está bien definida entre versiones. En cambio, mire la respuesta de @terdon, ya que resuelve todos los problemas de esta solución.
Paddy Landau

6

Puedes usar find con -execlike,

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

Esto va a funcionar si el archivo tiene un espacio en el nombre.


3

Un método no terminal.

Simplemente seleccione los archivos zip, haga clic derecho en uno y elija extract here. Puede seleccionar todos o solo una cantidad de archivos zip a la vez.


1

unzip \*.zip o unzip '*.zip'

Lo obvio unzip *.zipno funciona, porque el shell lo expande unzip foo.zip bar.zip ...e unzipinterpreta el primer nombre de archivo como el archivo zip, y los siguientes nombres de archivo como archivos para extraer de ese archivo zip.

Sin embargo, unzipes un poco inusual entre los comandos de Unix ya que realiza sus propias expansiones globales. Si el *shell no lo expande, descomprimir lo hará e interpretará todos los nombres de archivo resultantes como archivos zip para procesar. Entonces, en este caso especial, uno puede escapar sin un forbucle o xargssimilar.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.