20

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? – Emanuil Rusev Dec 17 '18 at 17:09
  • 1
    The accepted anwer answers your question: unzip -d foo foo.zip. – Fabby Dec 18 '18 at 0:28
  • 2
    @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. – Emanuil Rusev Dec 18 '18 at 9:32
  • It seems to me that another answer there, by n.st does what you want? – Jeff Schaller Mar 6 '19 at 15:47
20

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.

2
  • 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) – Colin D May 13 '19 at 13:58
  • now that's an answer, complete with recommendations – austin Nov 15 '20 at 23:42
16

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
  • 2
    additional tip: use basename to make it more robust. (already upvoted though) **;-) – Fabby Dec 18 '18 at 10:49
1

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

for f in `ls -1 *.zip`; do unzip $f -d `basename $f .zip`; done

For just one file (i.e. to use an alias) it would be:

unzip $1 -d `basename $1 .zip`

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.