2009-05-26 35 views
5

Tôi có một thư mục có lưu trữ zip chứa hình ảnh .jpg, .png, .gif. Tôi muốn giải nén từng kho lưu trữ chỉ lấy các hình ảnh và đặt chúng vào một thư mục có tên của kho lưu trữ.giải nén tiện ích mở rộng cụ thể chỉ

Vì vậy:

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

mở archive1.zip - mất sunflower.jpg, rose_sun.gif. Tạo một tệp thư mục/lưu trữ1/và thêm hình ảnh vào thư mục đó, do đó tệp/archive1/folder1.jpg, files/archive1/rose_sun.gif. Làm điều này cho mỗi kho lưu trữ.

Tôi thực sự không biết làm thế nào điều này có thể được thực hiện, tất cả các đề xuất được hoan nghênh. Tôi có hơn 600 lưu trữ và một giải pháp tự động sẽ là một phao cứu sinh, tốt hơn là một giải pháp Linux.

Trả lời

1

cái gì đó dọc theo dòng:

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

này được thử nghiệm và sẽ xử lý khoảng trống trong tên tập tin (cả các tập tin zip và các file trích xuất) . Bạn có thể có va chạm nếu tệp zip có cùng tên tệp trong các thư mục khác nhau (bạn không thể tránh điều này nếu bạn định làm phẳng cấu trúc thư mục).

+0

Đây sẽ là một giải pháp tuyệt vời, ngoại trừ thư mục tạm thời kết thúc lên lãng phí IO và tài nguyên hệ thống. Bạn nên thêm ký tự đại diện vào cuộc gọi giải nén. (Thêm '* .jpg' '* .png' '* .gif' vào cuối.) Ngoài ra, bạn nên tránh sao chép tệp zip và thay vào đó hãy sử dụng "unzip ../${newfile}/zip". – MiffTheFox

+0

Tôi không tin rằng mức độ hiệu quả là một mối quan tâm thực sự ở đây, điều này trông giống như một hoạt động một shot cho tôi (hoặc một trong đó sẽ không được thực hiện thường xuyên đủ để đảm bảo over-kỹ thuật). Kết quả cuối cùng là những gì OP muốn, các tập tin đồ họa trong một thư mục cụ thể dựa trên tên lưu trữ. – paxdiablo

+0

vâng, điều này sẽ là một điều một lần :), tôi đoán tôi đang thử nghiệm tất cả các giải pháp ngay bây giờ, tại địa phương, hơn sẽ thử nó trên một số lượng lớn hơn của zips trên máy chủ – vache

4

7zip có thể thực hiện việc này và có Linux version.

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

(Chỉ cần kiểm tra nó, nó hoạt động.)

+0

hãy để tôi dùng thử ngay bây giờ tx – vache

+0

nhưng tôi sẽ phải chạy nó cho mỗi zip tôi có thể thêm một vòng lặp trong thời gian hay gì đó không? – vache

1

Bạn có thể viết một chương trình sử dụng thư viện zip. Nếu bạn làm Mono, bạn có thể sử dụng DotNetZip.

Mã này sẽ trông như thế này:

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

tôi cũng muốn giữ nó trên Linux, vì vậy tốt hơn là không. Net, nhưng hơn tôi sẽ có thể làm điều tương tự này cho phép nói rằng bằng cách sử dụng một thư viện zip java không? – vache

+0

Xin lỗi, tôi không biết liệu các thư viện zip Java có chức năng tương tự hay không. Ý tôi là, tôi chắc chắn bạn có thể làm điều đó, đó là một vấn đề đơn giản của lập trình. Nhưng câu hỏi là lập trình bao nhiêu. Khi bạn ay "Tôi muốn giữ nó trên Linux, tốt nhất là không .NET" - bạn có biết Mono chạy trên Linux không? Nói cách khác, bạn có thể sử dụng C# và .NET trên Linux. – Cheeso

1

Perl's Archive-Zip là thư viện tốt để nén/giải nén.

0

Dưới đây là quan điểm của tôi về câu trả lời đầu tiên ...

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

hoặc, nếu bạn chỉ muốn sử dụng lệnh giải nén bình thường ...

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

tôi đã không kiểm tra điều này, nhưng nó sẽ làm việc ... hoặc một cái gì đó dọc theo những dòng này. Chắc chắn hiệu quả hơn so với giải pháp đầu tiên. :)

Hy vọng điều này sẽ hữu ích!

4

Trong ngắn

Bạn có thể làm điều này với một lớp lót tìm + giải nén.

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

Trong Xem chi tiết

unzip phép bạn chỉ định các tập tin bạn muốn:

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

-d một thư mục đích:

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

Kết hợp với một find, và bạn có thể trích xuất tất cả các hình ảnh trong tất cả kéo khóa:

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

Sử dụng unzip -j để rác tách cấu trúc thư mục nội bộ của zip, chúng ta có thể làm tất cả trong một lệnh. Điều này cung cấp cho bạn danh sách hình ảnh phẳng được phân cách bằng tên zip mà bạn mong muốn là một lớp lót.

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

Một hạn chế là unzip -d sẽ không tạo ra nhiều hơn một cấp độ mới về thư mục, vì vậy chỉ cần mkdir images đầu tiên. Thưởng thức.

Các vấn đề liên quan