Search code examples
python-3.xunzipzip7zip

How to unzip archive directly into target folder without creating a subfolder with the archive name (7zip, command line)?


I'm using the 7zip command line interface to extract archives, like so:

7za.exe x -y {path_to_zipfile} -o{path_to_target_folder}

If my zipfile is named my_archive.7z, then I get the following filestructure in the target folder:

🗁 target_folder
 └─ 🗁 my_archive
     ├─ 🗋 foo.png
     ├─ 🗁 bar
     │   ├─ 🗋 baz.txt
     │   └─ 🗋 qux.txt
    ...

However, I don't want the subfolder 🗁 my_archive. I'm looking for flags to apply on the 7zip command such that everything extracts directly in the target folder, without creating the 🗁 my_archive subfolder.


NOTES

  • I can't replace x with e because the filestructure shouldn't be lost (the e flag pushes all files to the toplevel).

  • I'm working on a Windows 10 computer, but the solution must also work on Linux.

  • I'm using the following version: 7-Zip (a) 19.00 (x64)

  • Some background info: I'm calling 7zip from a Python program, like so:

    # Variables:
    # 'sevenzip_abspath': absolute path to 7za executable
    # 'zipfile_abspath': absolute path to zipped file (`.7z` format)
    # 'targetdir_abspath': absolute path to target directory
    commandlist = [
        sevenzip_abspath,
        'x',
        '-y',
        zipfile_abspath,
        f'-o{targetdir_abspath}',
    ]
    output = subprocess.Popen(
        commandlist,
        stdout=subprocess.PIPE,
        shell=False,
    ).communicate()[0]
    if output is not None:
        print(output.decode('utf-8'))
    

    I know I could do all kinds of things in Python after the unzipping has finished (move/rename directories, etc etc), but that's for plan B. First I want to check if there is an elegant solution.

  • I'd like to stick to 7zip for reasons that would lead us too far here.


Solution

  • You can rename the top level folder to match the target folder before extracting the archive.

    7za rn {path_to_zipfile} my_archive target_folder
    

    This will permanently change the archive. If you don't want that, take a copy first.