So, I forayed into creating a batch file to recompress lots of zip or rar files into the slightly higher compressed 7zip format. This is was to more tightly compact lots of random zip files I have in various places, and to stop Windows not helpfully searching them slowly whenever I did a search (I bet I can disable it, but it is useful for some vary limited amount of zip files). You’ll need the 7zip program to do this, and most of the examples here should be easily modifiable to suit needs. Yes, batch files are old ๐ but I don’t have another working scripting language handily installed. ๐
These are also very basic batch files. They don’t contain confirmations or much in the way of error checking besides what I describe below, so be careful if you do use them. Run the files from the directory you want the script to work on, in Windows XP you can just double click on the .bat files to do this (it’ll also pause at the end of execution just in case you want to re-read anything).
Basic Compression
Relearning the batch scripts, here we go ๐ First, I got this up and running:
REM Test1.bat Batch file to run 7zip on a folder to 7zip it "C:\Program Files\7-Zip\7z" a -t7z testarchive.7z testarchive\ pause
It did what it says on the tin – my sample folder was compressed. I wanted to check what it compressed – in this case, it created a 7zip file with the testarchive folder in addition to it’s contents. This is what I want to avoid ๐
For extracting files, there was a good example in the actual 7zip help file:
REM Test2.bat - extracting files "C:\Program Files\7-Zip\7z" x *.zip -o* pause
Worked fine on my sample of zip files, for instance, my ASTROFC.zip file with one ASTROFC.exe file in it got extracted to the subdirectory ASTROFC (ending up with the file ASTROFC\ASTROFC.exe available). I need a specific file, so I test this line too:
REM Test3.bat - testing extracting one file "C:\Program Files\7-Zip\7z" x ASTROFC.zip -o"ASTROFC.zip contents" pause
Works perfectly – I want to make sure it is some folder with a post or prefix, since other folders might have already been extracted (I tend to leave them around sometimes). This means no accidental deletes will happen.
The For Loop
So, onto the For loop. The page here was pretty useful. I’ve only made a few necessary batch files before, and not needed many loops.
My For loop at first should print out the filenames that I want to work on, as I’m going for rar and zip, we have:
REM Test4.bat - tell me what rar and zip files are in the current directory. for %%X in (*.rar *.zip) do echo %%X pause
Worked fine! Now a final thing is to get just the filename with no extension for the final 7zip file itself. The Microsoft site helps with this (with that, I also rename the variable "X" with "F" for file):
REM Test5.bat - tell me what rar and zip files are in the current directory with no extension. for %%F in (*.rar *.zip) do echo %%~nF pause
This just omitted any .rar or .zip extensions – will be useful in a bit. Finally, we want it to extract these folders using 7zip to the "*filename* contents" folders:
REM Test6.bat - unzip all the zip and rar files into "*filename* contents" folders for %%F in (*.rar *.zip) do "C:\Program Files\7-Zip\7z" x "%%F" -o"%%F contents" pause
This produced the required folders (eg: "ASTROFC.zip contents" as described above). Now to do this along with compressing the files:
REM Test7.bat - unzip all zips and rars. Create new 7z files from the same names. for %%F in (*.rar *.zip) do "C:\Program Files\7-Zip\7z" x "%%F" -o"%%F contents" for %%F in (*.rar *.zip) do "C:\Program Files\7-Zip\7z" a -t7z "%%~nF".7z "%%F contents\" pause
Now, this successfully created the right archives, with the right files (with default compression settings, which I’ll get to changing in a bit), but there is still the problem of it also adding the top level folder "filename contents" to the archive. I need to fix this! Currently it uses simply the archive "a" command’s "this folder and it’s contents" parameter.
REM Test9.bat - loop, try with no subfile directory for %%F in (*.rar *.zip) do "C:\Program Files\7-Zip\7z" x "%%F" -o"%%F contents" for %%F in (*.rar *.zip) do ( CD "%%F contents" "C:\Program Files\7-Zip\7z" a -t7z "../%%~nF.7z" * CD .. ) pause
I learned how to do multiple things in a do command – ( ) seems to work. Silly how I didn’t find that until some random page on call, which I could have used I guess, showed me.
With that, I can start to merge some bits. But first, I need to delete both the original zip file, and the "filename contents" folder. To do this, using DEL and RMDIR. See this code for notes, and the links for more.
REM Test10.bat - del and deltree to remove the archive REM /F is "Force if read only" and /Q is "Quiet" - no confirmation DEL testarchive.zip /F /Q REM /S is also "Subdirectories" and /Q is "Quiet" - no confirmation RMDIR testarchive /S /Q pause
So now I can use this, pretty easily. Putting this all together we have:
REM Test11.bat - putting it all together. for %%F in (*.rar *.zip) do ( REM Extract... "C:\Program Files\7-Zip\7z" x "%%F" -o"%%F contents" REM Change directory, create 7zip of contents of directory... CD "%%F contents" "C:\Program Files\7-Zip\7z" a -t7z "../%%~nF.7z" * CD .. REM Delete the old files DEL "%%F" /F /Q RMDIR "%%F contents" /S /Q ) pause
It works! It creates identically named files but 7zip archives, using the standard routines. Then deletes the old files and the temp directory. At first, it didn’t work properly since I missed quotes for the DEL and RMDIR commands, oops! Added them back in fast. Okay, now to add some additional stuff…
Additional Nice Stuff
What if the zip isn’t correctly extracted? a "filename contents" folder won’t be created. Therefore, if I run the "create 7zip" part, 7zip compressing will, after testing, just run on the root directory since the CD "filename contents"
will fail – and also put it on the folder below the current one (in my case, the root of my drive). Then the rest of the script fails since it is in the root of the drive and not a subdirectory (ouch!). I’ll use a quick if statement to stop this using the "exists" command just to make sure. I’m not going to add too many error checking things (which could check for the 7zip’s exit code among other bits) because for my limited needs, I don’t need a fully automated solution.
REM Test12.bat - adding "If" error checking for %%F in (*.rar *.zip) do ( REM Extract... "C:\Program Files\7-Zip\7z" x "%%F" -o"%%F contents" REM Does the directory exist? has 7zip created it correctly? IF EXIST "%%F contents" ( REM Change directory, create 7zip of contents of directory... CD "%%F contents" "C:\Program Files\7-Zip\7z" a -t7z "../%%~nF.7z" * CD .. REM Delete the old files DEL "%%F" /F /Q RMDIR "%%F contents" /S /Q ) ) pause
I also want to make it look nicer. I don’t need every command shown on the command line – without the command @ECHO OFF
even my REM statements get sent to the command line. If I ever want to debug, turning off this by removing this line at the top of the file is pretty easy (although 7zip’s output carries on). So here we go, some ECHO comments added too:
@ECHO OFF REM Test13.bat - echo comments ECHO Searching for RAR and ZIP files to recompress into 7zip archives. for %%F in (*.rar *.zip) do ( ECHO Found %%F to recompress... REM Extract... "C:\Program Files\7-Zip\7z" x "%%F" -o"%%F contents" REM Does the directory exist? has 7zip created it correctly? IF EXIST "%%F contents" ( REM Change directory, create 7zip of contents of directory... CD "%%F contents" "C:\Program Files\7-Zip\7z" a -t7z "../%%~nF.7z" * CD .. REM Delete the old files DEL "%%F" /F /Q RMDIR "%%F contents" /S /Q ECHO Recompressed %%F to %%~nF.7z and deleted %%F. ) ) ECHO Search ended. pause
Finally, I want to compress the 7zip archives to maximum quality. This is quite easy, and is stated pretty easily in the manual – it’s just the addition of -mx=9
(-m being "modifiers", x being "level of compression" and we want it to be 9, the maximum, so "=9"). This last addition makes it pretty much complete, so I rename the script to zip_7zip_automated_delete.bat
, ready to be copied
@ECHO OFF REM zip_to_7zip_automated_delete.bat - find all .zip and .rar files in the current directory, recompress them into 7zip files and delete the originals. Skip ones that don't decompress. ECHO Searching for RAR and ZIP files to recompress into 7zip archives. for %%F in (*.rar *.zip) do ( ECHO Found %%F to recompress... REM Extract... "C:\Program Files\7-Zip\7z" x "%%F" -o"%%F contents" REM Does the directory exist? has 7zip created it correctly? IF EXIST "%%F contents" ( REM Change directory, create 7zip of contents of directory... CD "%%F contents" "C:\Program Files\7-Zip\7z" a -t7z "../%%~nF.7z" * -mx=9 CD .. REM Delete the old files DEL "%%F" /F /Q RMDIR "%%F contents" /S /Q ECHO Recompressed %%F to %%~nF.7z and deleted %%F. ) ) ECHO Search ended. pause
Whew! Now .zip and .rar files can be all be recompressed in a directory automatically at maximum settings.
Separate 7zip creation and deletion of zip files
Finally, the one thing I wanted to make sure was that the 7zip files got created successfully and delete the zip files only then. The easiest way to do this was from another batch file, but first needing to remove the DEL and DELTREE from the original.
@ECHO OFF REM zip_to_7zip.bat - find all .zip and .rar files in the current directory, recompress them into 7zip files - but don't delete the originals. ECHO Searching for RAR and ZIP files to recompress into 7zip archives. for %%F in (*.rar *.zip) do ( ECHO Found %%F to recompress... REM Extract... "C:\Program Files\7-Zip\7z" x "%%F" -o"%%F contents" REM Does the directory exist? has 7zip created it correctly? IF EXIST "%%F contents" ( REM Change directory, create 7zip of contents of directory... CD "%%F contents" "C:\Program Files\7-Zip\7z" a -t7z "../%%~nF.7z" * -mx=9 CD .. REM Delete the temporary extraction folder RMDIR "%%F contents" /S /Q ECHO Recompressed %%F to %%~nF.7z ) ) ECHO Search ended. pause
Then move them to their dedicated file as below:
@ECHO OFF REM zip_automated_delete.bat - find all .zip and .rar files in the current directory delete them if a "filename.7z" file exists for them in the same directory. ECHO Searching for RAR and ZIP files to delete for %%F in (*.rar *.zip) do ( ECHO Found %%F to possibly delete... REM Check IF EXIST "%%~nF.7z" ( REM Delete the old file, we have a copy DEL "%%F" /F /Q ECHO Found %%~nF.7z so can delete %%F. Deleted. ) ELSE ( ECHO Cannot delete %%F, no %%~nF.7z file found. ) ) ECHO Search ended. pause
Working on Subfolders
I was interested to see if I could get it to work on subfolders as easily as a single folder, although since I don’t add much error checking it might cause some errors, but is useful for running on a large amount of files ๐ In any case, the altered script looks like this to create the files:
@ECHO OFF REM zip_to_7zip_subfolders.bat - find all .zip and .rar files in the current directory and all subfolders, recompress them into 7zip files - but don't delete the originals. set ROOTDIR=%CD% ECHO Searching for RAR and ZIP files to recompress into 7zip archives. for /R "%ROOTDIR%" %%F in (*.rar *.zip) do ( ECHO Found %%F to recompress... REM Extract... "C:\Program Files\7-Zip\7z" x "%%F" -o"%%F contents" REM Does the directory exist? has 7zip created it correctly? IF EXIST "%%~fF contents" ( REM Change directory, create 7zip of contents of directory... CD "%%~fF contents" "C:\Program Files\7-Zip\7z" a -t7z "../%%~nF.7z" * -mx=9 CD "%ROOTDIR%" REM Delete the temporary extraction folder RMDIR "%%~fF contents" /S /Q ECHO Recompressed %%F to %%~nF.7z ) ) ECHO Search ended. pause
And this to delete the zip files, this again makes sure a 7z file of the same name exists:
@ECHO OFF REM zip_subfolders_automated_delete.bat - find all .zip and .rar files in the current directory and all subfolders delete them if a "filename.7z" file exists for them in the same directory. set ROOTDIR=%CD% ECHO Searching for RAR and ZIP files to delete for /R "%ROOTDIR%" %%F in (*.rar *.zip) do ( ECHO Found %%F to possibly delete... REM Check IF EXIST "%%~pnF.7z" ( REM Delete the old file, we have a copy DEL "%%F" /F /Q ECHO Found %%~pnF.7z so can delete %%F. Deleted. ) ELSE ( ECHO Cannot delete %%F, no %%~pnF.7z file found. ) ) ECHO Search ended. pause
Pretty easy changes to the FOR loop parameters luckily, and the change to add in the "Working Directory" backtrack properly too using a variable.
Further Work
Since I only did this as an exercise to save some time, rather then to make anything that’ll stand the test of time, the batch file seriously lacks confirmation, logging and basic statistic parts (such as counting how many things were converted). There is also no "make a comparison" part for checking if I saved space or not (sometimes 7zip files can be bigger then well compressed zip files). At least it works though ๐
Resources
The files: BatchZipTo7Zip.7z (2KB) or BatchZipTo7Zip.zip (7KB) – should be all pretty much as above.
Via. Google searches and bookmarks, I used these webpages:
- http://technet.microsoft.com/en-gb/library/bb491071.aspx – Microsoft documentation. There are poor examples/explanations in places (and some links don’t work?), but the FOR loop documentation was to die for.
- http://www.computerhope.com/batch.htm – nice and basic information, with updates for XP
- http://commandwindows.com/batchfiles-iterating.htm – For loop! Nice intro to it
- http://www.robvanderwoude.com/batchfiles.html – Some random useful stuff here
PS: For WordPress users, using my normal quote button didn’t work, it kept adding trailing slashes, very odd, had to replace with the quot version. Wonder why it’s not fixed yet?
Excellent post, this is exactly what I was looking for, many thanks for sharing! I made few changes though – many of my ZIP files are backups with long path names, so the current path + the extracted paths were going over 255 chars and causing errors. I changed the script to always extract the ZIP archive in “F:\1”, and then move the 7z archive to where the original ZIP archive is located.
…
REM Extract…
“C:\Program Files\7-Zip\7z” x “%%F” -o”F:\1″
REM Does the directory exist? has 7zip created it correctly?
IF EXIST “F:\1” (
REM Change directory, create 7zip of contents of directory…
CD “F:\1”
“C:\Program Files\7-Zip\7z” a -t7z “../%%~nF.7z” * -mx=9
move “..\%%~nF.7z” “%%~pF”
CD “%ROOTDIR%”
REM Delete the temporary extraction folder
RMDIR “F:\1” /S /Q
…
Cool tip there, I never had large zips to convert (or at least not many files in them) so that’d be very helpful for those that do and have a drive with enough space. Glad you found it useful too, I need to write up a few more simple windows scripts but nothing really this useful, heh.
Nice! I made some changes to my version to add error checking.
Basically I check the ERRORLEVEL returned by the 7zip calls to make sure I am not recompressing bad zip/rar files and 7zip compression part did not fail.
Excellent job!!!
Hope that features like these will soon be added to 7-zip’s shell extension.
Thanks a lot!
Hey Andrew,
Good job, I would like that you can explain how to compress folders with 7-zip using a .bat file. See, in my job, I need to compress a packet of folders in a .zip file using a .bat file, but I need to control what folders will be zipped, because not everyone will be zipped as well the .bat file must run daily I need to have control of that too.
I cannot find the information that a need to do this, I hope you can help me with this, thanks a lot.
regards from Mexico
I’ve no idea how you’d start this, these scripts just work on recompressing Zip files, not folders! You’d need to edit it pretty heftily depending on what you need to do.
Jorge,
I believe your answer is here. Its a matter of changing one small part to compress directories rather than files. http://commandwindows.com/batchfiles-iterating.htm
I came across this because I was looking for exactly this. Thank you! I especially liked the script to recompress into 7z then delete the original archive. But like you mentioned, in some cases the RAR or ZIP may have a better compression ratio. I have modified the script a bit. After it is done compressing, it uses loops to compare the two files, output the archive name, 7z size, rar/zip size, and keep the smaller of the two. Here it is to anyone who is interested:
@ECHO OFF
REM Find all .zip and .rar files in the current directory, recompress them into 7zip files and delete the smaller version.
ECHO Searching for RAR and ZIP files to recompress into 7-Zip archives.
FOR %%F IN (*.rar *.zip) DO (
ECHO Found %%F to recompress…
REM Extract contents from the original file.
“C:\Program Files\7-Zip\7z” x “%%F” -o”%%F contents”
REM Check to see if 7-zip created the directory.
IF EXIST “%%F contents” (
REM Change directory, create 7zip of contents of directory.
CD “%%F contents”
“C:\Program Files\7-Zip\7z” a -t7z “../%%~nF.7z” * -m0=lzma -mx=9 -mmt2 -md=128m -ms=off
CD ..
REM Compare the RAR or Zip to the 7z, choose the smaller file, and cleanup the directory.
FOR %%G IN (*.7z) DO (
IF %%~nF == %%~nG (
ECHO.
ECHO Archive : %%~nF
ECHO 7-Zip Size : %%~zG Bytes
ECHO Original Size : %%~zF Bytes
ECHO.
IF %%~zF GTR %%~zG (
DEL “%%F” /F /Q
ECHO The 7z archive has a higher compression ratio.
ECHO Deleting the original archive.
) ELSE (
DEL “%%G” /F /Q
ECHO The original archive has a higher compression ratio.
ECHO Deleting the 7z archive.
)
ECHO.
)
)
RMDIR “%%F contents” /S /Q
)
)
ECHO Search has ended.
ECHO.
ECHO Press any key to close this window.
PAUSE > nul
Just for the heck of it, I decided to take it a bit further. Instead of spamming a bunch of code in this comment box, I’ll just add a link where I’m hosting it if anyone wants to try it out:
http://bmgcl.emuxhaven.net/downloads.htm – Scroll to the bottom of the page.
Now the script can: Check for zip/rar files, decompress, recompress into 7z, compare, delete the larger file, error check if the archive is corrupt, and output all actions into a log file. It does pretty much everything that you mentioned was missing, besides counting the number of files converted. I did not add this because I felt it was kind of redundant, the user should know how many files he/she is attempting to convert. Besides, the log will display ERROR if contents did not extract. Maybe I’ll add it in the future if I’m bored…
I made sure to give credit to Andrew for this wonderful script, it has helped me in so many ways.
i have the following program to extract the zip file which is in c:\ source to designation folder when ever i run the batch file i get message
already exit override with i don’t want this message is there i way to suppress this message
@echo off
setlocal enabledelayedexpansion
set SOURCE_DIR=C:\Source
set DEST_DIR=C:\Destination
set FILENAMES_TO_COPY=*.7z *.zip
set COPYCMD=/-Y
ECHO Searching for RAR and ZIP files to recompress into 7zip archives.
for /R “%SOURCE_DIR%” %%F IN (%FILENAMES_TO_COPY%) do (
ECHO File %%F
IF NOT EXIST “%%~nF.zip ” (
ECHO in 7z %%F
REM Extract…
“C:\Program Files\7-Zip \7z” x “%%F” -o”%%F contents”
REM Does the directory exist? has 7zip created it correctly?
IF EXIST “%%F contents” (
REM Change directory, create 7zip of contents of directory…
CD “%%F contents”
“C:\Program Files\7-Zip\7z” a -tzip “../%%~nF.zip ” * -mx=9
REM CD ..
REM Delete the old files
DEL “%%F” /F /Q
RMDIR “%%F contents” /S /Q
ECHO Recompressed %%F to %%~nF.zip and deleted %%F.
)
)
)
for /R “%SOURCE_DIR%” %%F IN (%FILENAMES_TO_COPY%) do (
IF EXIST “%%~nF.zip ” (
ECHO in zip %%~nF
set FILE_DIR=%%~dpF
set FILE_INTERMEDIATE_DIR=!FILE_DIR:%SOURCE_DIR%=!
“C:\Program Files\7-Zip \7z” x “%%~nF.zip ” -o”%DEST_DIR%!FILE_INTERMEDIATE_DIR!”
)
)
Hi Andrew i need your help on the previous comments
As per my previous mail i used following command to suppressed Overwritten message.
set COPYCMD=/-Y
But i am not able to suppressed Overwritten message.
Is any another way to do the same.
thanks in advanced
Hi Andrew i need your help
I have one of above program to extract the zip file but I want to extract the file to the designation folder from source folder when ever i run the batch file
Thanks a lot
The batch script under “Separate 7zip creation and deletion of zip files” has numerous backslashes in the wrong places that will break the script. Once cleaned up, it worked fine. You should add a section on how to batch convert multiple 7zips into the more compatible zip format.
Code would be:
@ECHO OFF
REM 7zip_to_zip.bat – find all .7z files in the current directory, recompress them into zip files – but don’t delete the originals.
ECHO Searching for 7zip files to recompress into zip archives.
for %%F in (*.7z) do (
ECHO Found %%F to recompress…
REM Extract…
“C:\Program Files\7-Zip\7z” x “%%F” -o”%%F contents”
REM Does the directory exist? has 7zip created it correctly?
IF EXIST “%%F contents” (
REM Change directory, create zip of contents of directory…
CD “%%F contents”
“C:\Program Files\7-Zip\7z” a -tzip “../%%~nF.zip” * -mx=9
CD ..
REM Delete the temporary extraction folder
RMDIR “%%F contents” /S /Q
ECHO Recompressed %%F to %%~nF.zip
)
)
ECHO Search ended.
pause
Jeffrey Hartwick
ERROR: 7zip_to_zip.bat in windows 8 64bits, fix please.
running 7zip for second error
—–7zip_to_zip.bat
@ECHO OFF
REM 7zip_to_zip.bat โ find all .7z files in the current directory, recompress them into zip files โ but donโt delete the originals.
ECHO Buscando archivos 7zip para recomprimir a archivo zip
for %%F in (*.7z) do (
ECHO Se encontro %%F para recomprimir
REM Extraerโฆ
7z.exe x “%%F” -o”%%F contents”
REM Does the directory exist? has 7zip created it correctly?
IF EXIST “%%F contents” (
REM Change directory, create zip of contents of directoryโฆ
CD “%%F contents”
7z.exe a -tzip “../%%~nF.zip” * -mx=9
CD ..
REM Delete the temporary extraction folder
RMDIR “%%F contents” /S /Q
ECHO Recompressed %%F to %%~nF.zip
)
)
ECHO Search ended.
pause
nota: copy 7zip.exe junto al .bat
install: C:\Program Files (x86)\7-Zip
HELP please!!!
You’ll need to install the 64 bit version of 7-zip, see the 7-zip downloads page for the MSI – I’d uninstall your current one before you install the new one however. ๐
Thank you so much for your scripts!!! I was just about to write the same codes but yours are perfect ๐