53

How to unzip a file (ex: foo.zip) to a folder with the same name (foo/)?

Basically, I want to create an alias of unzip that unzips files into a folder with the same name (instead of the current folder). That's how Mac's unzip utility works and I want to do the same in CLI.

4
  • @Christopher I don't see how it's a duplicate. Can you find an answer to my question in that question? Commented Dec 17, 2018 at 17:09
  • 1
    The accepted anwer answers your question: unzip -d foo foo.zip. Commented Dec 18, 2018 at 0:28
  • 3
    @Fabby, no it doesn't, I need a dynamic solution that won't require adding the name of the target folder. I believe the second paragraph makes this very clear. Commented Dec 18, 2018 at 9:32
  • It seems to me that another answer there, by n.st does what you want? Commented Mar 6, 2019 at 15:47

3 Answers 3

45

I use unar for this; by default, if an archive contains more than one top-level file or directory, it creates a directory to store the extracted contents, named after the archive in the way you describe:

unar foo.zip 

You can force the creation of a directory in all cases with the -d option:

unar -d foo.zip 

Alternatively, a function can do this with unzip:

unzd() { if [[ $# != 1 ]]; then echo I need a single argument, the name of the archive to extract; return 1; fi target="${1%.zip}" unzip "$1" -d "${target##*/}" } 

The

target=${1%.zip} 

line removes the .zip extension, with no regard for anything else (so foo.zip becomes foo, and ~/foo.zip becomes ~/foo). The

${target##*/} 

parameter expansion removes anything up to the last /, so ~/foo becomes foo. This means that the function extracts any .zip file to a directory named after it, in the current directory. Use unzip $1 -d "${target}" if you want to extract the archive to a directory alongside it instead.

unar is available for macOS (along with its GUI application, The Unarchiver), Windows, and Linux; it is packaged in many distributions, e.g. unar in Debian and derivatives, Fedora and derivatives, community/unarchiver in Arch Linux.

2
  • 1
    Smoothing over this behavior for unzip, 7z, unrar, etc is just crazy....glad to see unar can just do it all (I run parallel unar {} ::: *.zip *.rar *.7z) Commented May 13, 2019 at 13:58
  • unar is perfect. Commented May 27, 2023 at 16:36
31

Just one another variant to do that with a 1-liner for multiple zip files in current dir:

for f in *.zip; do unzip "$f" -d "${f%.zip}"; done 

For just one file (i.e. to use in a function) it would be:

unzip "$1" -d "${1%.zip}" 
0
23

Use unzip -d exdir zipfile.zip to extract a zipfile into a particular directory. In principle from reading your post literally you could write a function like this:

unzip_d () { unzip -d "$1" "$1" } 

Since you want the .zip extension removed though, you can use special variable syntax to do that:

unzip_d () { zipfile="$1" zipdir=${1%.zip} unzip -d "$zipdir" "$zipfile" } 
1
  • 3
    additional tip: use basename to make it more robust. (already upvoted though) **;-) Commented Dec 18, 2018 at 10:49

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.