Pergunta

Eu tenho um um diretório com zip arquivos contendo .jpg, .png, .gif imagens. Eu quero descompactar cada arquivo tomando as imagens somente e colocá-los em uma pasta com o nome do arquivo.

Assim:

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

Open archive1.zip - take sunflower.jpg, rose_sun.gif. Faça um arquivos de pasta / archive1 / e adicione as imagens para essa pasta, então arquivos / archive1 / folder1.jpg, arquivos / archive1 / rose_sun.gif. Faça isso para cada arquivo.

Eu realmente não sei como isso pode ser feito, todas as sugestões são bem vindas. Eu tenho mais de 600 arquivos e uma solução automática seria um salva-vidas, de preferência uma solução Linux.

Foi útil?

Solução

Algo ao longo das linhas 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

Esta é testado e irá lidar com espaços em nomes de arquivos (ambos os arquivos zip e os arquivos extraídos). Você pode ter colisões se o arquivo zip tem o mesmo nome do arquivo em diretórios diferentes (você não pode evitar isso se você estiver indo para achatar a estrutura de diretórios).

Outras dicas

Em Breve

Você pode fazer isso com um one-liner achado + descompactação.

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

em detalhe

unzip permite que você especifique os arquivos que deseja:

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

E -d um diretório de destino:

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

Combine isso com um find, e você pode extrair todas as imagens em todos os zips:

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

Usando unzip -j jogar fora a extração de estrutura de diretório interno do fecho de correr, podemos fazer tudo isso em um comando. Isto dá-lhe a lista de imagem plana separados por nome zip que você deseja como um one-liner.

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

A limitação é que unzip -d não vai criar mais do que um novo nível de diretórios, por isso só mkdir images primeiro. Desfrute.

7zip pode fazer isso, e tem uma Linux versão .

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

(Apenas testado, ele funciona.)

Você pode escrever um programa usando uma biblioteca de zip. Se você fizer Mono, você pode usar DotNetZip .

O código ficaria assim:

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");
            }
        }
    }
}

O Perl Arquivo-Zip é uma boa biblioteca para fechar / descompactação.

Aqui está a minha opinião sobre a primeira resposta ...

#!/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

ou, se você gostaria apenas de usar o comando normal de descompactação ...

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

Eu não testei isso, mas ele deve funcionar ... ou algo nesse sentido. Definitivamente mais eficiente do que a primeira solução. :)

Espero que isso ajude!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top