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?
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?
Jawaban:
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
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
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 rm
dengan 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 shopt
baris dengan setopt nullglob
.
Berikut ini adalah padanan portabel. Kondisi penghentian sedikit rumit karena find
tidak 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
unzip
tidak 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?
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($_);
}
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.zip
untuk 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 cd
masuk ke direktori yang diinginkan dengan file zip sebelum menggunakan ini).
atool
Perilaku di sini tidak berbeda secara signifikan dari unzip. Saya katakan, itu juga tidak mengekstrak file ZIP secara rekursif.
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.
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
}
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
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.