Search code examples
pythonzipunzip

Extracting inner file from zip file with python


I am able to extract the inner file, but it extracts the entire chain.
Suppose the following file structure

v a.zip
    v folder1
        v folder2
            > inner.txt

and suppose I want to extract inner.txt to some folder target.
Currently what happens when I try to do this is that I end up extracting folder1/folder2/inner.txt to target. Is it possible to extract the single file instead of the entire chain of directories? So that when target is opened, the only thing inside is inner.txt.

EDIT:
Using python zip module to unzip files and extract only the inner files to the desired location.


Solution

  • You should use the -j (junk paths (do not make directories)) modifier (old v5.52 has it). Here's the full list: [DIE.Linux]: unzip(1) - Linux man page, or you could simply run (${PATH_TO}/)unzip in the terminal, and it will output the argument list.

    Considering that you want to extract the file in a folder called target, use the command (you may need to specify the path to unzip):

    "unzip" -j "a.zip" -d "target" "folder1/folder2/inner.txt"
    

    Output (Win, but for Nix it's the same thing):

    (py35x64_test) c:\Work\Dev\StackOverflow\q047439536>"unzip" -j "a.zip" -d "target" "folder1/folder2/inner.txt"
    Archive:  a.zip
      inflating: target/inner.txt
    

    Output (without -j):

    (py35x64_test) c:\Work\Dev\StackOverflow\q047439536>"unzip" "a.zip" -d "target" "folder1/folder2/inner.txt"
    Archive:  a.zip
      inflating: target/folder1/folder2/inner.txt
    

    Or, since you mentioned Python,

    code00.py:

    import os
    from zipfile import ZipFile
    
    
    def extract_without_folder(arc_name, full_item_name, folder):
        with ZipFile(arc_name) as zf:
            file_data = zf.read(full_item_name)
        with open(os.path.join(folder, os.path.basename(full_item_name)), "wb") as fout:
            fout.write(file_data)
    
    
    if __name__ == "__main__":
        extract_without_folder("a.zip", "folder1/folder2/inner.txt", "target")