Mengekompresi banyak file sekaligus

27

Saya memiliki lebih dari 200 .zipfile dalam satu folder. Saya tidak ingin mendekompres satu per satu. Saya ingin mengekstraknya menggunakan perintah atau skrip tunggal. Bagaimana cara melakukannya.

g_p
sumber

Jawaban:

38

Jika Anda benar-benar ingin mengompresnya secara paralel, Anda bisa melakukannya

for i in *zip; do unzip "$i" & done

Namun itu, akan meluncurkan proses N untuk file .zip N dan bisa sangat berat pada sistem Anda. Untuk pendekatan yang lebih terkontrol, meluncurkan hanya 10 proses paralel pada suatu waktu, coba ini:

find . -name '*.zip' -print0 | xargs -0 -I {} -P 10 unzip {}

Untuk mengontrol jumlah proses paralel yang diluncurkan, ubah -Pke apa pun yang Anda inginkan. Jika Anda tidak ingin pengulangan ke subdirektori, lakukan ini sebagai gantinya:

find . -maxdepth 1 -name '*.zip' -print0 | xargs -0 -I {} -P 10 unzip {}

Atau, Anda dapat menginstal paralel GNU seperti yang disarankan oleh @OleTange di komentar dan jalankan

parallel unzip ::: *zip
terdon
sumber
3
Menjalankan secara paralel adalah ide yang bagus, tetapi bukankah disk I / O akan menjadi hambatan utama?
Paddy Landau
1
@ PaddyLandau tidak yakin, saya harus memeriksa. Ini akan tergantung pada kecepatan algoritma dekompresi vs kecepatan disk yang saya bayangkan.
terdon
Gunakan -execatau -execdirbukannya perpipaan ke xargs. Tidak hanya lebih sederhana untuk dipahami, tetapi juga lebih sedikit rawan kesalahan dan menggunakan lebih sedikit sumber daya sistem. find . -name '*.zip' -exec unzip {} ';'(Anda harus mengutip tanda titik koma.)
Paddy Landau
@ PaddyLandau satu-satunya alasan saya melakukan piping ke xargs adalah untuk menjalankan berbagai hal secara paralel seperti yang diminta OP. -exec \;(Anda dapat menghindari koma, tidak perlu tanda kutip), akan menjalankan setiap perintah secara berurutan. -exec +lebih baik tetapi tidak akan bekerja di sini karena itu bukan cara unzipkerjanya.
terdon
Saya pikir kita telah memahami OP secara berbeda. Anda membacanya sebagai menginginkannya secara paralel, sedangkan saya memahaminya sebagai makna satu perintah, bukan beberapa perintah. Yah, dia punya kedua metode sekarang :)
Paddy Landau
17

The GNU paralel perintah baik cocok untuk hal semacam ini. Setelah:

$ sudo apt-get install parallel

Kemudian

ls *.zip | parallel unzip

Ini akan menggunakan sebanyak inti yang Anda miliki, menjaga setiap inti sibuk dengan unzip, sampai semuanya selesai.

Wayne Conrad
sumber
Ini adalah ide yang lebih baik untuk digunakan echo *.zipsebagai gantinya untuk mencegah kemungkinan alias dari menyelinap dalam info tambahan. Namun, ini memiliki masalah yang sama dengan jawaban @ Guru, itu terpecah pada nama file yang mengandung spasi.
nyuszika7h
1
@ nyuszika7h Berbeda dengan xargsGNU Paralel tidak merusak nama file yang mengandung spasi / tab / kutipan. Hanya jika nama file berisi baris baru Anda harus lebih berhati-hati. Misalnya dengan menggunakan:parallel unzip ::: *.zip
Ole Tange
@ nyuszika7h - Ini adalah alasan bagus untuk menghindari kedua perintah standar alias , dan menempatkan spasi dalam nama file.
Wayne Conrad
@ nyuszika7h menggunakan echosama buruknya dengan menggunakan ls. Globbing dan loop sementara adalah yang paling aman.
terdon
1
@NateEldredge Sementara peluang itu lebih besar di masa ketika sistem hanya memiliki satu disk magnetik, hari ini dengan RAID dengan banyak spindle dan flash disk peluang itu lebih kecil. Hal terbaik untuk dilakukan tentu saja adalah mengukur dan melihat bagaimana sistem Anda berperilaku. Saya baru-baru ini menggunakan 40 spindle RAID di mana paralelisme optimal untuk proses lapar I / O adalah 10: Itu tidak memberikan kecepatan 10x - hanya 6x, tetapi kurang dari 10 proses memberi kurang dari 6x.
Ole Tange
12

Anda dapat menggunakan perintah berikut:

Pertama, ubah direktori di terminal ke direktori yang berisi file .zip:

cd /path

Kemudian jalankan perintah ini untuk unzip semua file .zip:

for z in *.zip; do unzip "$z"; done
nux
sumber
10

Jika Anda memiliki banyak .zipfile di folder Anda dan Anda ingin mendekompres semuanya, buka terminal dan buka folder Anda menggunakan:

cd <path_to_folder>

Sekarang gunakan perintah ini untuk mendekompres semua .zipfile Anda :

ls *.zip | xargs -n1 unzip
g_p
sumber
3
Ini akan gagal jika salah satu nama file berisi spasi.
terdon
1
ya kamu benar.
g_p
Ini adalah ide yang lebih baik untuk digunakan echo *.zipsebagai gantinya untuk mencegah kemungkinan lsalias menyelinap di info tambahan, namun itu masih tidak memperbaiki masalah spasi putih.
nyuszika7h
1
@ OleTange Jika Anda tidak melihat, saya mengatakan bahwa itu masih gagal pada nama file dengan spasi putih di dalamnya.
nyuszika7h
1
Jangan pernah bergantung pada output dari lsuntuk skrip, karena outputnya tidak didefinisikan dengan baik di antara versi. Alih-alih lihat jawaban dari @terdon karena itu memecahkan semua masalah dari solusi ini.
Paddy Landau
6

Anda dapat menggunakan find dengan -execseperti itu,

find . -name "*.zip" -exec unzip {} \;

Ini akan berfungsi jika file memiliki spasi di namanya.

Elliott Frisch
sumber
3

Metode non terminal.

Cukup pilih file zip, klik kanan pada salah satu dan pilih extract here. Anda dapat memilih semua atau hanya sejumlah file zip sekaligus.

Parto
sumber
1

unzip \*.zip atau unzip '*.zip'

Jelas unzip *.ziptidak bekerja, karena shell mengekspansi unzip foo.zip bar.zip ...dan unzipmenafsirkan nama file pertama sebagai file zip, dan nama file berikut sebagai file untuk diekstrak dari file zip itu.

Namun, unzipagak tidak biasa di antara perintah Unix dalam melakukan ekspansi globnya sendiri. Jika *tidak diperluas oleh shell, unzip akan melakukannya, dan intepret semua nama file yang dihasilkan sebagai file zip yang akan diproses. Jadi dalam kasus khusus ini, seseorang dapat pergi tanpa forlingkaran atau xargssejenisnya.

Nate Eldredge
sumber