How can I do a dynamic search of zip files in a particular path (e.g.:/opt/uploading/"*"/multiple .zip files) and unzip it into the same folder with the zip files?

Below function is unzipping multiple zip files and removing zip files. But I want zip files to be there with the unzip files.

while true; do
   find -iname '*.zip' > zipindex
   test -s zipindex || break
   for zip in $(cat zipindex); do unzip -o $zip && rm $zip; done
  • So, to clarify, you'd like to extract all zip archives in the directory tree, and any zip files inside them, but avoid extracting the same file again? Doesn't that loop extract the archives in the current directory, instead of the location of the archive? Is that what you wanted? – ilkkachu Apr 18 '17 at 8:34
  • Yes, I expect to extract all zip archives in the directory tree and any zip files inside them, but avoid extracting the same file again. but I need those unzipped files in a folder and zipped files in a folder so that we can avoid duplicates or else let me know how to handle the duplicates with these code. – keerthi Apr 18 '17 at 9:29

Well the rm $zip is removing the .Zip files, so remove it.

  • If I remove "rm $zip" the for loop continuously loop which is not correct. – keerthi Apr 18 '17 at 7:17
  • Yes I see that. My mistake. But as long as they are there you will keep unzipping them. How often do you run this on the same dir? – Dennis Anderson Apr 18 '17 at 8:00
  • whenever the .zip files arrive, so many times i do... – keerthi Apr 18 '17 at 9:22

This is much more suited for a for loop than a while loop. This way you can also get rid of the needless saving of results from find -iname '*.zip' > zipindex

Do something like this instead:


for zip in $(find -iname '*.zip'); do
    unzip -o $zip

This will iterate through all of the lines that find produces.

Of course, you should just dispense with the bash script altogether and make a find oneliner like so:

find -iname '*.zip' -execdir unzip {} \;

EDIT: Thanks to @don_crissti and @ilkkachu, I've managed to get rid of calling another instance of the shell in -exec. -execdir is good to know!

  • don't do that... - use find with -exec – don_crissti Apr 18 '17 at 12:05
  • I was just about to edit that in, actually @don_crissti :) – user6075516 Apr 18 '17 at 12:13
  • :) don't do that either: embedding {} in the shell code is always wrong. – don_crissti Apr 18 '17 at 12:19
  • Use -execdir to do the extraction in the directory containing the archive. Though this will still have problems with nested archives, the find might not find them all. (e.g. assume z.zip containing a.zip and that find sees the files in alphabetical order) – ilkkachu Apr 18 '17 at 12:19
  • 1
    Thanks for the comments and suggestions! Although it can be a bit disheartening at times, (especially when you get reprimanded twice, he he) it is always good to learn something new! – user6075516 Apr 18 '17 at 12:46

Using GNU Parallel you could do this:

find my_dir | grep -E '\.zip$' | parallel unzip
inotifywait -qmre MOVED_TO -e CLOSE_WRITE --format %w%f my_dir | grep  -E '\.zip$' | parallel -u unzip

This way you do not need to busy wait for the next zip file to show up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.