extensão específica de descompactação única
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.
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!