Mengekstrak file zip bersarang


15

Saya memiliki banyak arsip zip, yang masing-masing berisi sejumlah arsip zip. Apa cara terbaik untuk mengekstrak semua file yang terkandung dalam arsip zip ini dan arsip zip-nya secara rekursif, yang bukan arsip zip itu sendiri?


apa yang Anda maksud dengan mengekstraksi hal-hal yang bukan file zip? Anda ingin menyalinnya ke tempat lain?
phunehehe

Saya tidak menemukan persyaratan Anda jelas. Saya menemukan Shawn J. Goff dan interpretasi saya tentang kemungkinan yang sama. Bisakah Anda mengklarifikasi?
Gilles 'SANGAT berhenti menjadi jahat'

@Gilles: Maaf, ya itu agak tidak jelas. Saya mengubahnya sedikit, semoga lebih jelas sekarang.
oadams

Saya akan memposting jawaban, tapi saya percaya itu harusnya sebagai komentar: Nested Archives menambah ruang yang Anda butuhkan! Anda mungkin memaksudkan format file Zip, bukan hanya gzip. setiap file zip sudah dikompres, mengompres mereka lagi, hanya menciptakan lebih banyak overhead, secara efektif menambah ruang yang dibutuhkan.
polemon

Ya, saya tidak melakukannya: P. Sayangnya saya mengalami cara aneh untuk mendistribusikan file.
oadams

Jawaban:


13

Ini akan mengekstrak semua file zip ke direktori saat ini, tidak termasuk file zip yang ada di dalamnya.

find . -type f -name '*.zip' -exec unzip -- '{}' -x '*.zip' \;

Meskipun ini mengekstraksi konten ke direktori saat ini, tidak semua file akan berakhir secara ketat di direktori ini karena konten dapat menyertakan subdirektori.

Jika Anda benar-benar menginginkan semua file secara ketat di direktori saat ini, Anda dapat menjalankannya

find . -type f -mindepth 2 -exec mv -- '{}' . \;

Catatan: ini akan clobber file jika ada dua dengan nama yang sama di direktori yang berbeda.

Jika Anda ingin mengekstraksi semua file zip dan zip secara terkandung di dalamnya, berikut ini mengekstrak semua file zip di direktori saat ini dan semua zip yang terkandung di dalamnya ke direktori saat ini.

while [ "`find . -type f -name '*.zip' | wc -l`" -gt 0 ]
do
    find . -type f -name "*.zip" -exec unzip -- '{}' \; -exec rm -- '{}' \;
done

loop sementara ini banyak membantu saya dalam kompetisi peretasan etis di mana mereka telah menyiapkan file zip bersarang dengan level 3.337, terima kasih!
pipi

2
Anda mungkin menyukai varian ini yang saya gunakan untuk mengekstrak konten dari telinga bersarang, perang, file jar: gist.github.com/tyrcho/479c18795d997c201e53 Perbedaan utama adalah membuat folder bersarang untuk setiap arsip. while [ "Temukan . -type f -name '*.? ar' | wc-l" -gt 0 ]; do find -type f -name "*.?ar" -exec mkdir -p '{}.dir' \; -exec unzip -d '{}.dir' -- '../{}' \; -exec rm -- '{}' \;; done
Michel Daviot

4

Sejauh yang saya mengerti, Anda memiliki arsip zip yang berisi arsip zip sendiri, dan Anda ingin unzip zip bersarang setiap kali satu diekstrak.

Berikut ini adalah skrip bash 4 yang membuka ritsleting semua ritsleting di direktori saat ini dan subdirektori secara rekursif, menghapus setiap file zip setelah ritsleting, dan terus berjalan selama ada file zip. File zip dalam subdirektori diekstraksi relatif terhadap subdirektori itu. Peringatan: belum diuji, buat cadangan file asli sebelum mencobanya atau ganti rmdengan memindahkan file zip di luar pohon direktori .

shopt -s globstar nullglob
while set -- **/*.zip; [ $# -ge 1 ] do
  for z; do
    ( cd -- "$(dirname "$z")" &&
      z=${z##*/} &&
      unzip -- "$z" &&
      rm -- "$z"
    )
  done
done

Script juga akan berfungsi di zsh jika Anda mengganti shoptbaris dengan setopt nullglob.

Berikut ini adalah padanan portabel. Kondisi penghentian sedikit rumit karena findtidak secara spontan mengembalikan status untuk menunjukkan apakah telah menemukan file. Peringatan: seperti di atas.

while [ -n "$(find . -type f -name '*.zip' -exec sh -c '
    cd "${z%/*}" &&
    z=${z##*/} &&
    unzip -- "$z" 1>&2 &&
    rm -- "$z" &&
    echo 1
')" ]; do :; done

1

unziptidak melakukan ini, karena cara UNIX adalah melakukan satu hal dan melakukannya dengan baik, tidak menangani semua kasus khusus yang gila di setiap alat. Dengan demikian, Anda perlu menggunakan shell (yang melakukan pekerjaan "mengikat semuanya" dengan baik). Ini membuatnya menjadi pertanyaan pemrograman, dan karena SEMUA pertanyaan pemrograman yang mungkin telah dijawab di StackOverflow, di sini: Bagaimana Anda secara unzip mengarsipkan arsip dalam direktori dan subdirektori dari baris perintah Unix?


1
Saya pasti tidak akan menyebut "menggunakan shell" pertanyaan pemrograman, dan "shell scripting" terdaftar di FAQ sebagai topik
Michael Mrozek

Saya tidak bermaksud mengatakan bahwa itu di luar topik sama sekali, saya hanya ingin membenarkan mengapa itu ada di topik di StackOverflow.
Thomas Themel

1

Script perl ini akan mengekstrak setiap file .zip ke dalam subdirektori sendiri. Jalankan skrip lebih dari sekali untuk menangani file zip bersarang. Itu tidak menghapus file .zip setelah ekstraksi tetapi Anda bisa melakukan perubahan itu dengan menambahkan panggilan unlink ().

#!/usr/bin/perl -w

# This script unzips all .zip files it finds in the current directory
# and all subdirectories.  Contents are extracted into a subdirectory
# named after the zip file (eg. a.zip is extracted into a/).
# Run the script multiple times until all nested zip files are
# extracted.  This is public domain software.

use strict;
use Cwd;

sub process_zip {
    my $file = shift || die;
    (my $dir = $file) =~ s,/[^/]+$,,;
    (my $bare_file = $file);
    $bare_file =~ s,.*/,,;
    my $file_nopath = $bare_file;
    $bare_file =~ s,\.zip$,,;
    my $old_dir = getcwd();
    chdir($dir) or die "Could not chdir from '$old_dir' to '$dir': $!";
    if (-d $bare_file) {
        chdir($old_dir);
        # assume zip already extracted
        return;
    }
    mkdir($bare_file);
    chdir($bare_file);
    system("unzip '../$file_nopath'");
    chdir($old_dir);
}

my $cmd = "find . -name '*.zip'";
open(my $fh, "$cmd |") or die "Error running '$cmd': $!";
while(<$fh>) {
    chomp;
    process_zip($_);
}

1

Cara termudah adalah dengan menggunakan atool: http://www.nongnu.org/atool/ Ini adalah skrip yang sangat bagus yang menggunakan program zip, unzip, tar, rar dll untuk mengekstrak arsip apa pun.

Gunakan atool -x package_name.zipuntuk unzip semuanya atau jika Anda ingin menggunakannya dalam direktori dengan banyak file zip gunakan sederhanafor loop :

for f in *; do atool -x $f; fi(Anda harus cdmasuk ke direktori yang diinginkan dengan file zip sebelum menggunakan ini).


atoolPerilaku di sini tidak berbeda secara signifikan dari unzip. Saya katakan, itu juga tidak mengekstrak file ZIP secara rekursif.
Thomas Themel

@ Thomas Themel: Apakah Anda yakin itu tidak mengekstrak file ZIP secara rekursif? Itu dapat mengekstrak dari file deb tar.gz secara rekursif tetapi saya tidak punya waktu atm untuk mengujinya dengan arsip zip bersarang: \

0

Anda harus berhati-hati membuka ritsleting file zip di dalam file zip:

http://research.swtch.com/2010/03/zip-files-all-way-down.html

Dimungkinkan untuk membuat file zip yang menghasilkan file zip sebagai output, yang menghasilkan file zip sebagai output, dll. Dll. Artinya, Anda dapat membuat file zip yang merupakan salep tetap untuk "unzip" program.

Juga, saya ingat orang membuat file zip yang akan "meledak", yaitu file zip yang sangat kecil akan unzip ke multi-gigabytes output. Ini adalah aspek dari metode kompresi.


0

Mungkin ini akan membantu (bekerja untuk saya):

function unzipAll(){

# find and count archives
archLst=`find . -type f -name "*.*ar"`
archLstSize=`echo $archLst| awk 'END{print NF}'`

# while archives exists do extract loop
while [ "$archLstSize" -gt 0 ]; do

# extract and remove all archives (found on single iteration)
for x in $archLst; do 
mv "${x}" "${x}_";
unzip "${x}_" -d "${x}" && rm "${x}_"; 
done; #EO for

# find and count archives
archLst=`find . -type f -name "*.*ar"`
archLstSize=`echo $archLst| awk 'END{print NF}'`

done #EO while

}

0

Saya membutuhkan solusi seperti Giles dari 2010, kecuali saya perlu melestarikan struktur folder, tidak meng-unzip semuanya ke direktori tingkat atas. Inilah pendapat saya tentang dia dengan tiga baris ditambahkan / diubah:

#!/bin/bash
shopt -s globstar nullglob
while set -- **/*.zip; [ $# -ge 1 ]
do
    for z
    do
        ( cd -- "$(dirname "$z")" &&
            z=${z##*/} &&
            cp -- "$z" "$z".bak &&
            mkdir -- "$z"dir &&
            unzip -- "$z" -d "$z"dir &&
            rm -- "$z"
        )
    done
done

0

Lihat utilitas nzip berbasis java ini untuk file zip bersarang. Mengekstrak dan mengompresi ritsleting yang tersarang dapat dilakukan dengan mudah menggunakan perintah berikut

java -jar nzip.jar -c list -s readme.zip

java -jar nzip.jar -c ekstrak -s "C: \ project \ readme.zip" -t readme

java -jar nzip.jar -c kompres -s readme -t "C: \ project \ readme.zip"

PS. Saya penulis dan akan dengan senang hati memperbaiki bug apa pun dengan cepat.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.