79

I have a file myarchive.zip that contains many directories, files, etc. Let's say this myarchive.zip file lives in a directory called "b". Well, when I use the "unzip myarchive.zip" command, the system creates a directory by default called "myarchive" with the contents of the zip file. I do not want the system to create this "myarchive" directory - I just want the contents to be extracted to directory "b". Is this possible?

What I've been doing now is simply issuing a "cp" command to copy the files from the newly created directory (in this case "myarchive" to "b") to where I want them.

3
  • 12
    By default, unzip doesn't create a directory. Your zip file probably has the directory at its top level.
    – Chris Down
    Commented Apr 18, 2013 at 3:29
  • 3
    You could use mv instead of cp. mv archive/* .; rmdir archive/ or similar. Commented Apr 18, 2013 at 3:35
  • @ChrisDown: my archive had only files inside, no subfolders, and yet unzip with no arguments extracted it into <archivename>/. Debian 12. Commented Nov 30, 2023 at 12:24

6 Answers 6

85

My version of unzip has a -j option to not create any directory.

So

unzip -j /path/to/file.zip

Will extract all the files into the current directory without restoring the directory structure stored in the zip file.

If you want to only remove one level of directories from the archive, (extract myarchive/dir/file as dir/file, not file), you could use bsdtar (which does supports zip files in addition to tar files) instead and its -s option.

bsdtar -xf /path/to/file.zip -s'|[^/]*/||'
4
  • 23
    When using -j the archive directory structure is not recreated and all files are deposited in the extraction folder. This means ALL subfolders are dropped. So if you would have zip/A/f1, zip/A/B/f2 and zip/A/B/C/f3 you would end up with a single folder with f1, f2, f3. It gets funky if you have files with the same name in different subfolders. Usually you want to just drop the top folder not the entire directory structure. Commented Feb 4, 2016 at 16:01
  • 4
    @CristianVrabie, well that's exactly what I'm saying in the answer. I've added a bsdtar alternative for what you're asking. See edit. Commented Feb 4, 2016 at 16:38
  • How could we get the file names extracted inside the /path/to/file.zip
    – alper
    Commented Dec 29, 2021 at 1:27
  • 1
    "gets funky" - THAT is an understatement!
    – AJM
    Commented Mar 28, 2023 at 15:46
15

Looks like this is really simple with bsdtar :

bsdtar --strip-components=1 -xvf file.zip

14

What the accepted answer doesn't specify how to do, as you say in the question, if you still want to extract to a specific folder without using the folders paths stored in the zip files, you can use the -j option with -d option in this way:

unzip -j /path/to/file.zip -d other_folder

or for your case

unzip -j myarchive.zip -d b
2
  • 5
    You're right that you can do that; but it won't create the subdirectories so you still have to incorporate another step; I'm pretty sure the OP wants to rename the root directory of the archive to another name but keep the remaining structure under that directory.
    – Pryftan
    Commented May 9, 2018 at 20:34
  • 1
    Very useful addition to the answer here though, this is the detail I was just searching for and I'm glad I scrolled down. More upvotes here folks. Commented Mar 2, 2020 at 19:23
7

Easily to do it with tips create temp folder then move files back to current directory ex:

unzip myfile.zip -d ./tmp
mv ./tmp/*/* .
4
  • 1
    How do you handle directories that are already present in /tmp before you extract the archive? Commented Aug 11, 2020 at 9:40
  • this is ./tmp not /tmp of system . We create tmp directory inside storaged zip file... so you can see all directories inside
    – Va Va
    Commented Sep 4, 2020 at 3:41
  • The question also applies to ./tmp. If it already exists, any files it contains will be moved along with the archive’s contents. One fix for that is to use mktemp -d. Commented Sep 4, 2020 at 4:44
  • This approach works for me, although I prefer tmp=$(mktemp -d ./tmp-XXXX) instead of ./tmp.
    – ceremcem
    Commented Mar 9, 2021 at 0:59
3

Assuming you are in the b directory already:

tar zxvf myarchive.zip --strip-components=1

Otherwise:

tar zxvf b/myarchive.zip --strip-components=1 -C b/
-1

If performing unzip myarchive.zip produces a directory myarchive with everything in it, then that means the creator of the zip file actually performed zip on that directory.

The only way to create what you want is to just move all the contents outside the directory after you perform unzip:

[user@host]:some/path/b$ unzip myarchive.zip

[user@host]:some/path/b$ ls {shows directory myarchive}

[user@host]:some/path/b$ mv myarchive/* .

[user@host]:some/path/b$ rm -R myarchive

[user@host]:some/path/b$ ls {shows first level of myarchive (directly in b)}

3
  • 3
    you also need a mv myarchive/.* . to move all the hidden files like .gitignore and .htaccess. Commented Sep 5, 2017 at 6:34
  • 2
    @KinjalDixit That was my thinking too; Antoine there's a fatal flaw in your example as Kinjai points out: because you use rm -R and because you're not using ls -a you're not showing if there are any dot files; now what happens when you run rm -R and there are dot files? You've not copied them so they're lost. You really should fix that and maybe explain the difference because it's something that will trip up newbies quite a lot; and consider this: what if it's not an archive they have? Or what if they add to the command to delete the archive once it's uncompressed?
    – Pryftan
    Commented May 9, 2018 at 20:22
  • 1
    Otoh rmdir would make sure it's empty first... But if the user doesn't know about dot files it'd confuse them.
    – Pryftan
    Commented May 9, 2018 at 20:23

You must log in to answer this question.

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