How do I archive with subdirectories using the 7-Zip command line? Or, how do I KEEP the folder structure while archiving?

I have a bunch of files like this:

C:\G\G1\35antique-shop.mp3
C:\G\G2\35antique-shop.mp3
C:\G\G1\09saguri.mp3
C:\G\G2\09saguri.mp3

I just want to know how to keep the folder structure while archiving. This is more important than the duplicate thing, to know how to solve that, would be a bonus.

@Lamb "Do you want to archive only selective files (not the whole folder content) from the G1 and G2 folders?"

That almost says it all, but I'll try to improve: Not only do I want to move only some selected files to an archive. I also have a list of these files, including path-names to each file.

So, in SubDir1 there might be 10 files, of which I want to zip three, and in SubDir1\sub2 there might be five files, of which I want to zip all five. The files that I need to archive are in a listfile.

There might be duplicate files, so my hope is that with subdirectories added, 7-Zip does NOT see them as duplicates.

And I like to do it on the command line.

I've tried a batch file like this:

7z a -r MyArchive.7z C:\G\G1\35antique-shop.mp3
7z a -r MyArchive.7z C:\G\G2\35antique-shop.mp3
7z a -r MyArchive.7z C:\G\G1\09saguri.mp3
7z a -r MyArchive.7z C:\G\G2\09saguri.mp3

This also means that files 01antique-shop.mp3, 02antique-shop.mp3, ...., til 33antique-shop.mp3 and 34antique-shop.mp3, should NOT be archived.

The foldernames (=subdirectories) weren't added to MyArchive.7z, and this is the problem.

Obviously, I'd like to use just one commando with a listfile, but that doesn't work either.

I've tried:

7z a -mx0 -tzip C:\$$-edrive\F-G-H.zip @fgh.txt

which actually works pretty fine as far as the selecting goes, but it does NOT keep the directory structure. Sadly.

How do I do this?


Solution 1:

The latest stable version of 7-Zip (15.14) has the switch -spf that enables the absolute path storage.

For example, if the file list.txt is

C:\tmp\dir1\file.txt
C:\tmp\dir2\file.txt

the command 7z a p.7z -spf @list.txt will produce an archive storing the absolute paths as is in the list. Alternatively, the command 7z a p.7z -spf2 @list.txt will remove the drive letter:

tmp\dir1\file.txt
tmp\dir2\file.txt

If the file list.txt is

dir1\file.txt
dir2\file.txt

the command 7z a p.7z @list.txt will store the relative paths as is in the list, in both versions 9.20 and 15.14.

I did more tests with the switch -spf. The results are here.

Solution 2:

I got it to archive a directory with subdirectories using the following:

7z.exe a - t7z NewArchivePath PathOfFolderToArchive

Solution 3:

Try this instead:

cd /d C:\
7z a MyArchive.7z G\G1\35antique-shop.mp3
7z a MyArchive.7z G\G2\35antique-shop.mp3
7z a MyArchive.7z G\G1\09saguri.mp3
7z a MyArchive.7z G\G2\09saguri.mp3

The problem seems to be that people have been requesting for years for proper path storage options (just as they have for the ability to modify multi-volume archives), but the author doesn't seem to be interested. That's part of the reason why I started using WinRAR so much.


If you have a listfile, 7-Zip will not store paths if the files to be archived do not share a single top-level directory. For example if you have Input.txt containing the following:

C:\path to\file1.ext
D:\path to\file1.ext
E:\path to\file1.ext

If you run 7z a MyArchive.7z @Input.txt, you'll see that the paths have been stripped completely, which seems completely backwards to me (OTOH rar a MyArchive.rar @Input.txt does the job just fine).

So to overcome 7-Zip's deficiency, you can use a batch file as follows:

for /f "tokens=1* delims=\" %%i in (Input.txt) do (
    pushd %%i\
    7z a D:\MyArchive.7z "%%j"
    popd
)

Note: Replace D:\MyArchive.7z with the proper path to your destination archive. Also, the batch file should work irrespective of whether you have quoted paths in your listfile or not.


Edit: If your listfile looks like:

"C:\$$-edrive\F\faithless.-.long.way.mp3"
"C:\$$-edrive\G\Antique Shop.mp3"

or

"\$$-edrive\F\faithless.-.long.way.mp3"
"\$$-edrive\G\Antique Shop.mp3"

then edit it to look like this instead:

"$$-edrive\F\faithless.-.long.way.mp3"
"$$-edrive\G\Antique Shop.mp3"

Now assuming all files to be archived are under C:\$$-edrive, navigate to C:\ and run 7z a C:\MyArchive.7z @C:\Input.txt. Using a listfile the paths will be saved only if no drive letters are present, no initial backslashes are there and if the top-level (root) directory is the same for all files. Also, for best results I advise you not to create MyArchive.7z in C:\$$-edrive.