60

I have many zip files (a.zip, b.zip, c.zip, ...) and I want to extract each of them into new folders with the same name as the archive's name (a, b, c, ...) via terminal.

Actually, what I want is a solution that I can use later with a find, because I actually have many folders (2014, 2013, 2012, ...) each of which containing many zip files (a.zip, b.zip, ...).

If I do:

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

it will unzip all the files and put them into their respective parent folder.

Michael
  • 735

5 Answers5

97

You should be able to use unzip's -d option to set an alternate directory for the archive contents.

unzip -d a a.zip
unzip -d b b.zip

and so on. Within a find expression, you should be able to derive the name for the directory from the name of the zipfile using shell parameter expansion e.g.

find . -name '*.zip' -exec sh -c 'unzip -d "${1%.*}" "$1"' _ {} \;

Test it first by adding an echo i.e.

find . -name '*.zip' -exec sh -c 'echo unzip -d "${1%.*}" "$1"' _ {} \;

or something like

while read -rd $'\0' f; do 
  unzip -d "${f%.*}" "$f"
done < <(find . -name '*.zip' -print0)
cmcginty
  • 6,016
steeldriver
  • 142,475
48

I came looking for this myself, only to realize I'd already done it with other commands and it could be applied to just about anything else, the way I was already doing it.

The find method is crazy over-complicated for no reason.

for i in *.zip; do unzip "$i" -d "${i%%.zip}"; done
kencinder
  • 579
  • 4
  • 4
6

Simply Use

unzip '*.zip' -d /home/user/folder/
muru
  • 207,228
3

I also needed to do this using unrar. This can be achieved by a minor modification to kencinder's code.

for i in *.rar; do mkdir "${i%%.rar}"; unrar x -r "$i" "${i%%.rar}"; done 

PS: I wanted to add this as a comment but I don't have enough reputation points!

0
for z in *.zip; do unar -d "$z"; done