2009-05-26 20 views
5

Tengo un directorio con archivos comprimidos que contienen imágenes .jpg, .png, .gif. Quiero descomprimir cada archivo tomando solo las imágenes y ponerlas en una carpeta con el nombre del archivo.descomprimir solo la extensión específica

Así:

files/archive1.zip 
files/archive2.zip 
files/archive3.zip 
files/archive4.zip 

archive1.zip abierto - Tome sunflower.jpg, rose_sun.gif. Haga una carpeta files/archive1/y agregue las imágenes a esa carpeta, entonces files/archive1/folder1.jpg, files/archive1/rose_sun.gif. Haz esto a cada archivo.

Realmente no sé cómo se puede hacer, todas las sugerencias son bienvenidas. Tengo más de 600 archivos y una solución automática sería un salvavidas, preferiblemente una solución de Linux.

Respuesta

1

Algo a lo largo de las líneas de:

#!/bin/bash 
cd ~/basedir/files 
for file in *.zip ; do 
    newfile=$(echo "${file}" | sed -e 's/^files.//' -e 's/.zip$//') 
    echo ":${newfile}:" 
    mkdir tmp 
    rm -rf "${newfile}" 
    mkdir "${newfile}" 
    cp "${newfile}.zip" tmp 
    cd tmp 
    unzip "${newfile}.zip" 
    find . -name '*.jpg' -exec cp {} "../${newfile}" ';' 
    find . -name '*.gif' -exec cp {} "../${newfile}" ';' 
    cd .. 
    rm -rf tmp 
done 

Esto se prueba y se encargará de los espacios en los nombres de archivos (tanto los archivos zip y los archivos extraídos) . Puede tener colisiones si el archivo zip tiene el mismo nombre de archivo en diferentes directorios (no puede evitar esto si va a aplanar la estructura del directorio).

+0

Esta sería una excelente solución, excepto que el directorio temporal termina desperdiciando IO y recursos del sistema. Debe agregar comodines a la llamada descomprimir. (Agregue '* .jpg' '* .png' '* .gif' al final.) Además, debe evitar copiar el archivo zip, y en su lugar usar "descomprimir ../${newfile}/zip". – MiffTheFox

+0

No creo que el nivel de eficiencia sea una preocupación real aquí, esto me parece una operación única (o una que no se haría con la suficiente frecuencia como para justificar una sobreingeniería). El resultado final es lo que OP quería, los archivos gráficos en un directorio específico basado en el nombre del archivo. – paxdiablo

+0

sí, esto sería una cosa de una vez :), supongo que estoy probando todas estas soluciones en este momento, localmente, que lo probaré en una mayor cantidad de cremalleras en el servidor – vache

4

7zip puede hacer esto, y tiene un Linux version.

mkdir files/archive1 
7z e -ofiles/archive1/ files/archive1.zip *.jpg *.png *.gif 

(Sólo probado, funciona.)

+0

déjame intentarlo ahora tx – vache

+0

pero que tendría que ejecutar esto para cada zip ¿puedo agregar un bucle while, o algo así? – vache

1

se puede escribir un programa usando una biblioteca postal. Si haces Mono, puedes usar DotNetZip.

El código se vería así:

foreach (var archive in listOfZips) 
{ 
    using (var zip = ZipFile.Read(archive) 
    { 
     foreach (ZipEntry e in zip) 
     { 
      if (IsImageFile(e.FileName)) 
      { 
       e.FileName = System.IO.Path.Combine(archive.Replace(".zip",""), 
            System.IO.Path.GetFileName(e.FileName)); 
       e.Extract("files"); 
      } 
     } 
    } 
} 
+0

Bueno, quiero mantenerlo en Linux, por lo que preferiblemente no .net, pero de lo que debería ser capaz de hacer lo mismo digamos usando una biblioteca java zip no? – vache

+0

Lo siento, no sé si las bibliotecas zip de Java tienen una función similar. Quiero decir, estoy seguro de que podrías hacerlo, es una simple cuestión de programación. Pero la pregunta es cuánta programación. Cuando es posible "Quiero mantenerlo en Linux, preferiblemente no en .NET": ¿sabe que Mono se ejecuta en Linux? En otras palabras, puede usar C# y .NET en Linux. – Cheeso

1

Perl's Archive-Zip es una buena biblioteca para comprimir/descomprimir.

0

Esta es mi opinión sobre la primera respuesta ...

#!/bin/bash 
cd files 
for zip_name in *.zip ; do 
    dir_name=$(echo "${zip_name}" | sed -e 's/^files.//' -e 's/.zip$//') 
    mkdir ${dir_name} 
    7z e -o${dir_name}/ ${zip_name} *.jpg *.png *.gif 
done 

o, si lo que desea es utilizar el comando regular de descomprimir ...

unzip -d ${dir_name}/ ${zip_name} *.jpg *.png *.gif 

No he probado esto, pero debería funcionar ... o algo así. Definitivamente más eficiente que la primera solución. :)

Espero que esto ayude!

4

En Corto

Usted puede hacer esto con una sola línea encontrará + descomprimir.

find . -name "*.zip" -type f -exec unzip -jd "images/{}" "{}" "*.jpg" "*.png" "*.gif" \; 

en detalle

unzip le permite especificar los archivos que desea:

unzip archive.zip "*.jpg" "*.png" "*.gif" 

Y -d un directorio de destino:

unzip -d images/ archive.zip "*.jpg" "*.png" "*.gif" 

combinarlo con un find, y se puede extraer todas las imágenes de todas las cremalleras:

find . -name "*.zip" -type f -exec unzip -d images/ {} "*.jpg" "*.png" "*.gif" \; 

Usando unzip -j tirar a la basura la extracción de la estructura de directorio interno de la cremallera, podemos hacerlo todo en un solo comando. Esto le brinda la lista de imágenes planas separadas por nombre de zip que desea como una línea.

find . -name "*.zip" -type f -exec unzip -jd "images/{}" "{}" "*.jpg" "*.png" "*.gif" \; 

Una limitación es que unzip -d no creará más de un nuevo nivel de directorios, por lo que sólo mkdir images primero. Disfrutar.

Cuestiones relacionadas