78

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.

Anthon
  • 79,293

6 Answers6

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'|[^/]*/||'
  • 21
    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. – Cristian Vrabie Feb 04 '16 at 16:01
  • 3
    @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. – Stéphane Chazelas Feb 04 '16 at 16:38
  • How could we get the file names extracted inside the /path/to/file.zip – alper Dec 29 '21 at 01:27
  • "gets funky" - THAT is an understatement! – AJM Mar 28 '23 at 15:46
15

Looks like this is really simple with bsdtar :

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

ismail
  • 530
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
  • 4
    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 May 09 '18 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. – David Parks Mar 02 '20 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/*/* .
AdminBee
  • 22,803
Va Va
  • 71
  • 1
    How do you handle directories that are already present in /tmp before you extract the archive? – Stephen Kitt Aug 11 '20 at 09: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 Sep 04 '20 at 03: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. – Stephen Kitt Sep 04 '20 at 04:44
  • This approach works for me, although I prefer tmp=$(mktemp -d ./tmp-XXXX) instead of ./tmp. – ceremcem Mar 09 '21 at 00:59
2

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/
Trudy
  • 854
-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
    you also need a mv myarchive/.* . to move all the hidden files like .gitignore and .htaccess. – Kinjal Dixit Sep 05 '17 at 06: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 May 09 '18 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 May 09 '18 at 20:23