Given a .zip with the following example structure:


I need to be able to modify that internal file structure using 7zip command line tool like so:

1. I need to move all existing files to a new folder inside the archive (say prefix the stored paths with "/myfolder")

  1. I need to add another folder with other files (outside this question, resolved)

So, without unzipping, I would like to have the following structure as a result:


I know how to resolve point 2, but point 1 (changing the internal structure) is the one giving me trouble.

The reason for this requirement is that I am working with VERY large and complex archives with the sole purpose of rearranging the files and adding a few more in the same manner to all. It seems counterproductive to unzip for each file (that could take up to an hour) when I could do this easier.

Also, if there is another tool that can perform this task better (i.e. NOT 7zip, but some other free command line tool), I am open for suggestions.

Thank you kindly!

P.S. I am aware there might be a path length problem when increasing the directory path near 248 characters, but that is acceptable.

  • 1
    I don't think any tools will have that capability. You might be able to write something yourself using one of the 7zip API wrappers ... – DavidPostill Aug 16 '16 at 10:16

You can use the 7z rn command to move files and folders inside archives. Unfortunately it cannot move the root directory. You can however use a script to parse the output of 7z l and do it.

Here is a quick example in Python: (7z has to be available in PATH)

import os;
import subprocess;
import sys;

if len(sys.argv) < 3:
    print("Syntax: " + sys.argv[0] + " <archive> <subfolder>")

skip = True
renamed = []

proc = subprocess.Popen(["7z", "l", sys.argv[1]], stdout=subprocess.PIPE, universal_newlines=True)
for line in iter(proc.stdout.readline, ''):
    line_file = line.rstrip().split(" ")
    path = line_file[len(line_file) - 1]
    if path == "-" * 24:
        skip = not skip
    if not skip:
        path1 = path.split(os.sep)[0]
        if not path1 in renamed:
            newpath = sys.argv[2] + os.sep + path1
            proc = subprocess.run(["7z", "rn", sys.argv[1], path1, newpath], stdout=subprocess.DEVNULL, check=True)
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.