59

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.

1

5 Answers 5

95

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)
3
  • 5
    +1 for the test it first… part Dec 4, 2018 at 15:27
  • 2
    find needs a directory, so find . -name ...
    – slf
    Dec 31, 2018 at 16:41
  • 1
    @slf POSIXly, yes - but not in the case of GNU find ("If no starting-point is specified, . is assumed.") Dec 31, 2018 at 17:00
44

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
7
  • 4
    This is hands down the very best answer to the question at hand. The previous one is ridiculous and the one after this doesn't sort into the files respective root folders. Mar 6, 2019 at 19:56
  • How would one go about creating the directory without the .zip suffix? Asking for a friend.
    – dashard
    Apr 15, 2019 at 14:37
  • 1
    The answer does not create a directory with a .zip suffix, that is the very point of the portion within the braces.
    – kencinder
    Apr 15, 2019 at 16:13
  • 1
    Add make directory ${i%%.zip} , for i in *.zip; do mkdir ${i%%.zip}; unzip "$i" -d "${i%%.zip}"; done
    – Just_Alex
    Mar 13, 2021 at 9:46
  • 1
    Entirely unnecessary to invoke mkdir, that is what the -d flag is already doing.
    – kencinder
    Mar 13, 2021 at 20:31
6

Simply Use

unzip '*.zip' -d /home/user/folder/
1
  • 16
    Unless I'm missing something, this will unzip everything into /home/user/folder, not into /home/user/folder/a and /home/user/folder/b
    – M. Justin
    Mar 27, 2017 at 19:59
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
1
  • 7
    Welcome to AskUbuntu! Could you expand on this answer to explain why someone would want to do this? Generally it's ill advised to blindly run any old code one finds on the Internet 👍🏻
    – matigo
    Apr 6, 2022 at 13:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .