26

I have a ZIP file in which there is a top directory where all the files are stored:

Release/
Release/file
Release/subdirectory/file
Release/subdirectory/file2
Release/subdirectory/file3

I want to extract everything under Release, preserving the directory structure, but when I run this:

unzip archive.zip Release/* -d /tmp

It creates the top Release folder:

/tmp/Release/
/tmp/Release/file
/tmp/Release/subdirectory/file
/tmp/Release/subdirectory/file2
/tmp/Release/subdirectory/file3

How I can extract everything inside Release without creating a Release folder, like this:

/tmp/
/tmp/file
/tmp/subdirectory/file
/tmp/subdirectory/file2
/tmp/subdirectory/file3

4 Answers4

14

Create a symlink at the location that the top directory would be extracted to that points at your current location:

ln -s . Release && unzip <YourArchive>.zip

Then remove the link:

rm Release
ark
  • 156
5

The j flag should prevent folder creation unzip -j archive.zip -d .

From the man page:

-j 

junk paths. The archive's directory structure is not recreated; 
all files are deposited in the extraction directory (by default, the
current one).
Zanna
  • 72,312
jsta
  • 178
1

This is an old post but I faced with the same issue. For me the following really simple solution was working fine in bash:

$ cd abc 
$ unzip abc.zip -d ../

[-d exdir]

An optional directory to which to extract files. By default, all files and subdirectories are recreated in the current directory; the -d option allows extraction in an arbitrary directory (always assuming one has permission to write to the directory). This option need not appear at the end of the command line; it is also accepted before the zipfile specification (with the normal options), immediately after the zipfile specification, or between the file(s) and the -x option. The option and directory may be concatenated without any white space between them, but note that this may cause normal shell behavior to be suppressed. In particular, ''-d ~'' (tilde) is expanded by Unix C shells into the name of the user's home directory, but ''-d~'' is treated as a literal subdirectory ''~'' of the current directory.

Source: https://linux.die.net/man/1/unzip

zappee
  • 997
1

Python script for flattening extracted tree

The script written bellow extracts zip file and moves files contained within topmost directory out of it to the current working directory. This quick script is tailored to suit this particular question where there is one single topmost directory that contains all the files, although with a few edits can be made suitable for more general cases.

#!/usr/bin/env python3
import sys
import os
from zipfile import PyZipFile
for zip_file in sys.argv[1:]:
    pzf = PyZipFile(zip_file)
    namelist=pzf.namelist()
    top_dir = namelist[0]
    pzf.extractall(members=namelist[1:])
    for item in namelist[1:]:
        rename_args = [item,os.path.basename(item)]
        print(rename_args)
        os.rename(*rename_args)
    os.rmdir(top_dir)

Test run

Here's an example of how the script is supposed to work. Everything extracted to current working directory, but source file can be in differet directory altogether. The test is performed on the zip archive of my personal github repository.

$ ls                                                                                   
flatten_zip.py*  master.zip
$ ./flatten_zip.py master.zip                                                          
['utc-time-indicator-master/.gitignore', '.gitignore']
['utc-time-indicator-master/LICENSE', 'LICENSE']
['utc-time-indicator-master/utc-time-indicator', 'utc-time-indicator']
['utc-time-indicator-master/utc_indicator.png', 'utc_indicator.png']
$ ls
flatten_zip.py*  LICENSE  master.zip  utc_indicator.png  utc-time-indicator

Test with source file being in different location

$ mkdir test_unzip
$ cd test_unzip
$ ../flatten_zip.py  ../master.zip                                                     
['utc-time-indicator-master/.gitignore', '.gitignore']
['utc-time-indicator-master/LICENSE', 'LICENSE']
['utc-time-indicator-master/utc-time-indicator', 'utc-time-indicator']
['utc-time-indicator-master/utc_indicator.png', 'utc_indicator.png']
$ ls
LICENSE  utc_indicator.png  utc-time-indicator