Ekstraksi file .gz yang terkandung dalam folder

13

Saya memiliki folder yang berisi sekitar 320116 file .pdb.gz. Saya ingin membuka kompres mereka semua. Jika saya menggunakan gunzip * .gz itu memberi saya kesalahan yaitu daftar argumen terlalu panjang. Folder ini sekitar 2GB. Tolong beri saya saran yang tepat.

Lily Sharpton
sumber
Jika Anda harus bekerja pada struktur direktori ini dalam jangka panjang, bagi direktori ini menjadi banyak. Misalnya berdasarkan waktu modifikasi file atau nama file.
dan
Ya saya harus bekerja dalam jangka panjang. mereka telah diekstraksi sekarang saya ingin membagi dan mengklasifikasikannya menjadi tiga folder berdasarkan nama mereka. Apakah ada skrip shell untuk melakukannya?
Lily Sharpton
Saya sarankan Anda untuk mencari pertanyaan serupa di sana. Jika Anda tidak menemukan satu yang sesuai dengan kebutuhan Anda, ajukan pertanyaan baru Anda sendiri.
dan

Jawaban:

26
find . -name '*.pdb.gz' -exec gunzip {} +

-exec gunzip {} +akan memberikan gunzipbanyak tetapi tidak terlalu banyak nama file pada baris perintahnya. Ini lebih efisien daripada -exec gunzip {} \;yang memulai gunzipproses baru untuk setiap file.

John1024
sumber
3
Satu find, lebih sedikit gunzip!
dan
2
Perhatikan bahwa "+" adalah GNUism dan karenanya tidak akan bekerja pada sistem non-GNU seperti * BSD.
Pasang kembali Monica - M. Schröder
3
Versi BSD yang lebih baru findmemungkinkan notasi "+". Lihat, misalnya, yang findhalaman manual untuk BSD 10.1 . Juga berlaku untuk OS X (setidaknya 10.9 atau lebih baru, mungkin lebih awal).
Plasma
7

Setiap kali Anda mendapatkan kesalahan "daftar argumen terlalu lama", Anda dapat mengatasinya dengan menjalankan perintah yang diinginkan beberapa kali, setiap kali dengan subset argumen yang ingin Anda gunakan. xargsadalah alat yang membantu Anda melakukannya secara otomatis.

find . -type f -a -name \*.pdb.gz -print0 | xargs -0 gunzip
Celada
sumber
bukankah ini memiliki inefisiensi yang sama dengan -execdir gunzip "{}" \;xargs yang akan memanggil gunzip secara terpisah untuk setiap file? Itu adalah bacaan saya tentang halaman manual.
gogoud
5
Tidak, xargsakan memuat sebanyak mungkin nama file yang sesuai pada gunzipbaris perintah. Cobalah! echo a b c d e f | xargs echohanya memanggil echosekali dengan semua 6 argumen sehingga Anda melihat satu baris output (cukup perintah yang tidak berguna untuk dijalankan !!!!) sementara jika Anda memaksa xargsuntuk hanya menyediakan hingga 3 argumen per doa perintah menggunakan echo a b c d e f | xargs -n 3 echomaka Anda mendapatkan 2 baris output .
Celada
4
Keuntungan lain menggunakan xargsadalah bahwa, dengan -Popsi, Anda dapat menjalankan beberapa gunzipproses secara paralel, yang (tergantung pada parameter yang tepat dari sistem Anda) dapat berjalan lebih cepat.
psmears
terima kasih atas penunjuknya ke -P, @psmears. Sekarang saya belajar sesuatu juga!
Celada
1

Saya pikir ini harus bekerja, melewati jalur / nama setiap file secara individual ke gunzip untuk diproses:

find /my/dir -name "*.pdb.gz" -execdir gunzip "{}" \;
gogoud
sumber
1
Itu akan menjalankan gunzip sekali per file. Lihat jawaban John1024 untuk cara yang sedikit berbeda yang menghindari ketidakefisienan itu.
Celada
@Celada Ini disengaja; Kekhawatiran saya adalah bahwa menggunakan + mungkin sekali lagi mengarah ke pesan kesalahan karena kelebihan gunzip. Jika metode John1024 bekerja, secara teknis lebih efisien, tetapi metode saya harus bekerja jika tidak.
gogoud
1
finddengan +dan xargssecara tegas perancang dengan masalah itu dalam pikiran. Mereka akan selalu memberikan argumen sebanyak mungkin, sementara tidak melebihi batas sistem operasi. Karena, omong-omong, ini adalah batas sistem operasi, tidak ada hubungannya dengan gunzip.
Celada
1
@Celada ok terima kasih untuk info itu, jadi mungkin dengan '+' gunzip mungkin dipanggil lebih dari sekali, tetapi kurang dari 320.000 kali?
gogoud
1
benar.
Celada
1

Coba dengan cara ini:

find . -name '*.gz' -exec gunzip {} \;
jherran
sumber
3
Itu akan mengeksekusi gunzipsekali per file. Lihat jawaban John1024 untuk cara yang sedikit berbeda yang menghindari ketidakefisienan itu.
Celada
Pastikan untuk keluar dari * in * .gz ...
user253751
1

Jika Anda memiliki mesin multi-core Anda mungkin akan melihat bahwa menggunakan gunziptidak akan memaksimalkan kemampuan mesin Anda. Untuk itu Anda perlu menjalankan beberapa gunzips secara paralel. Untuk melacak yang dilakukan di mana terminal dengan tangan itu rumit, tetapi Anda dapat dengan mudah melakukannya dengan GNU paralel:

find . -name "*.gz" | parallel -X gunzip {}
Anthon
sumber
1
Bukankah itu akan gagal karena daftar argumen parallelterlalu panjang?
user253751
@immibis Ya, saya lupa masalah aslinya, saya akan memperbarui posting saya
Anthon
Bukankah itu masih gagal karena daftar argumen findterlalu panjang?
user253751
1
ya tetapi Anda melewatkan semua nama file pada findbaris perintah.
user253751
Sepertinya ini bukan hari yang baik untuk menjawab pertanyaan, saya lupa mengutip argumen untuk-name
Anthon
-1

Tidak perlu digunakan finduntuk ini, karena Anda tidak menyebutkan subfolder. Yang perlu Anda lakukan adalah:

for f in *.gz;do gunzip $f;done
Tolga Ozses
sumber
4
Anda memang perlu findjika Anda tidak ingin menelurkan 320116 gunzipproses, seperti halnya loop ini.
John WH Smith