2010-04-25 10 views
6

He visto bucles para descomprimir todos los archivos zip en un directorio. Sin embargo, antes de correr esto, yo preferiría asegurarse de que lo que estoy a punto de quedarse trabajará derecha:¿Puede un bucle de shell descomprimir todos los archivos en un directorio?

for i in dir; do cd $i; unzip '*.zip'; rm -rf *.zip; cd ..; done 

Básicamente quiero que se vea en la salida del "dir" ver todas las carpetas, para cada directorio cd, descomprima todos los archivos comprimidos, luego elimínelos, luego vuelva a copiar y vuelva a ejecutar hasta que no haya más.

¿Esto es algo que debería hacer en un solo comando o debería considerar hacer esto en Perl?

+1

Hola y bienvenidos a StackOverflow. Para que su código sea más legible, utilice la etiqueta de código –

+1

para su información, puede usar cd para volver al directorio anterior. – Aif

+0

@Patrick hecho :) – DVK

Respuesta

1

parcialmente probados:

find . -type d -exec sh -c "cd \"{}\" ; unzip \"*.zip\" ; rm \"*.zip\" " \; 

ejecuta la cadena cd/unzip/rm para cada subdirectorio.

+0

Hasta ahora esto funciona, donde la otra respuesta no podía tomar cosas como "Nombre de carpeta con espacio", sin embargo, no eliminaba los archivos .zip. – helpwithshell

+0

Creo que tienes que usar 'encontrar ... | xargs -0 ... 'para manejar espacios en blanco, o las citas escapadas hacen el trabajo? – Anycorn

+0

Al final pude modificar su línea de comando a: buscar. -name "* .zip" -exec sh -c "rm -rf \" {} \ "" \; para eliminar todos los archivos .zip sobrantes. Gracias – helpwithshell

1

Uso * para obtener el contenido del directorio actual:

for i in *; do cd "$i"; ...etc... ; done 

También debe asegurarse de que algo es un directorio antes de tratar de cd en él. En bash esto se hace de la siguiente manera:

if [ -d "$i" ]; then ...etc... ; fi 

También debe tener cuidado de comprobar que la operación de descompresión tuvo éxito antes de eliminar el archivo zip. No es necesario utilizar la eliminación de fuerza recursiva para eliminar un solo archivo.

Creo que esto está llegando al límite de lo que es sensato hacer una sola línea. Póngalo en un script de shell y formatéelo en múltiples líneas.

2

Debería estar bien en general. Para la depuración simplemente prefijando todos los comandos en el bucle con echo le dirá cómo se expanden las variables. También puede usar siempre rm -i en lugar de hacer que rm continúe con cualquier cosa con -f.

Las comillas simples en su llamada unzip solo descomprimirán los archivos llamados *.zip, es decir, * no se expandirán. Use comillas dobles en su lugar (o sin comillas).

Su bucle ahora supone que todos los directorios $i están directamente debajo del actual. Una solución más general sería usar la pila de directorio (pushd y popd);

for i in $dir; do 
    pushd $i 
    unzip *.zip 
    rm -rf *.zip 
    popd 
done 
+0

tuve que cambiar el primero de i en dir a por i en *, se deshizo cosas, sin embargo, tenía problemas con los archivos que contenían espacios en el nombre. – helpwithshell

+0

@help: Implícitamente asumí que 'dir' era una variable cuando no lo era, por lo que mi ejemplo era incorrecto. Se corrigió aquí y ahora se supone que 'dir' es una variable que contiene el listado del directorio. –

2

Unos sumando puntos a lo que han dicho:

  • Si pones un parámetro entre comillas simples, como en '*.zip', el depósito no será hacer extensión de la tarjeta salvaje y descomprimir intentará procesar un archivo literalmente se llama *.zip
  • No use -r como parámetro en rm si solo desea eliminar archivos individuales. Eso es innecesariamente peligroso, ya que probablemente no sea la eliminación recursiva de subdirectorios.
  • Debe comprobar el código de retorno de unzip y sólo quitar el archivo zip si descomprimir tuvo éxito (por ejemplo, usted podría decir if unzip *.zip; then rm *.zip; fi, o incluso utilizar un bucle explícito for para procesar los archivos zip uno por uno)
0

Cuando se desea saber si un algo va a funcionar, pero se resisten a sus consecuencias destructivas, hacen un poco a la vez:

Asegúrese de obtener los archivos de la derecha:

for i in dir; do cd $i; echo $i; cd ..; done 

Asegúrese de que puede descomprimir los archivos antes de eliminar los archivos:

for i in dir; do cd $i; unzip '*.zip'; cd ..; done 

Y, antes de hacer el Full Monty, hacer una copia de seguridad de su directorio.

Cuestiones relacionadas