23

i have a folder structure in this pattern. I've just shown two sub directories and 2 files in each but generally I have n number of subdirectories at a single level and single level of files (but can be n number of files)under them.

Directory master
subDirectory x:
  file1
  file2
Directory y:
  file 3
  file 4

I need to create a windows script, a batch file to run from the master directory and give me two zip files x.zip and y.zip containing their respective files.

I know my script has to use for and zip commands but I am going bonkers trying to get it to work as I can't understand from the syntax of these commands and googling doesnt seem to help.

I found a command like this for %f in ("*.*") do zip "%~nf.zip" "%f" but it seems to be working only if the files are directly there without subfolders.

James L.
  • 9,384
  • 5
  • 38
  • 77
user3085265
  • 233
  • 1
  • 2
  • 4

10 Answers10

22
for /d %%a in (*) do (ECHO zip -r -p "%%~na.zip" ".\%%a\*")

should work from within a batch.

Note that I've included an ECHO to simply SHOW the command that is proposed. You'd need to remove the ECHO keywor to EXECUTE the commands.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • Did u try it before or after include that ECHO line? – m3nda Dec 10 '13 at 06:19
  • Both ways. Do you see a problem? – Magoo Dec 10 '13 at 06:33
  • Yes, but maybe is because i used the zip.exe from cygwin. I type zip on mi Win7 cmd by first time on my live... and does nothing... so i got the cygwin one. Using @monacraft i got that a.zip is not compared to $a etcetc. I don't know what does the ~n... i dont need it to perform the same thing. Using your script, i got that \*\ is dos-style, a suggest to use posix /*/ and also, the same problem about comparison between the varname and filename. I can post the full error message if you're interested. – m3nda Dec 10 '13 at 06:52
  • 2
    the clear question is: can you use zip from cmd from scratch? – m3nda Dec 10 '13 at 06:52
  • 4
    Probably, NO. It's not an inbuilt command or supplied utility. I have a copy of Info-ZIP `zip.exe` on my path from when I installed `Free Pascal`. If you are using `Winzip` then you'd need the command-line support utility `WZZIP.exe`. Substituting `wzzip` for `zip` in this code produces similar results but with better compression. If you are using some other utility, well - YMMV. – Magoo Dec 10 '13 at 07:15
  • I say that i got the unique zip.exe i found, wich is from cygwin install. So if zip.exe is not built-in as i think... he would post wich zip.exe is using for. Right? So, maybe the code from answer below works too like yours... Will your code work with wzzip as well? So, i must try my code with wzzip. Thanks for the hint. – m3nda Dec 10 '13 at 07:27
  • I am very new to this, where should I put my source directory ? – Saurabh Bayani Nov 19 '15 at 11:31
  • @SaurabhBayani : Please create your own question - it costs nothing. You'd need to specify what it is that you want to do, in particular your "source directory" for what? The batch file itself or the data file you want to create or the utility executable that you want to use for the compression? – Magoo Nov 19 '15 at 14:10
  • I got error `%%a was unexpected at this time.` in windows 10 cmd – Chaminda Bandara Sep 26 '18 at 08:44
  • @ChamindaBandara : In that case, you are probably executing the command directly at the prompt. As posted, the command is intended to be executed within a batch file. To execute it from the prompt, change each `%%a` to `%a`. The entire point of batch files is to avoid repeatedly entering the same command - with the inevitable typos. – Magoo Sep 30 '18 at 11:39
11

I know its too late but if you still wanna try

for /d %%X in (*) do (for /d %%a in (%%X) do ( "C:\Program Files\7-Zip\7z.exe" a -tzip "%%X.zip" ".\%%a\" ))

here * is the current folder. for more options try this link

Sagar Sakre
  • 2,336
  • 22
  • 31
Arun Nallamayan
  • 361
  • 3
  • 4
7

No external dependency on 7zip or ZIP - create a vbs script and execute:

    @ECHO Zipping
    mkdir %TEMPDIR%
    xcopy /y /s %FILETOZIP% %TEMPDIR%
    echo Set objArgs = WScript.Arguments > _zipIt.vbs
    echo InputFolder = objArgs(0) >> _zipIt.vbs
    echo ZipFile = objArgs(1) >> _zipIt.vbs
    echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
    echo Set objShell = CreateObject("Shell.Application") >> _zipIt.vbs
    echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
    echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipIt.vbs
    @ECHO *******************************************
    @ECHO Zipping, please wait..
    echo wScript.Sleep 12000 >> _zipIt.vbs
    CScript  _zipIt.vbs  %TEMPDIR%  %OUTPUTZIP%
    del _zipIt.vbs
    rmdir /s /q  %TEMPDIR%

    @ECHO *******************************************
    @ECHO      ZIP Completed
PodTech.io
  • 4,874
  • 41
  • 24
  • do you know if this would work on a Windows XP machine? – user95227 Sep 22 '17 at 15:31
  • 1
    You've just created a dependency on VBScript instead. If you're going to do that, use a dependency that's not outdated, such as Powershell: >>> Compress-Archive -Path -DestinationPath .zip << – Antony Booth Sep 04 '19 at 01:37
  • I had to make some amendments to get it work on my end (Windows 10). [Here's](https://stackoverflow.com/a/59769968/1016343) what I changed. – Matt Jan 16 '20 at 12:56
  • @Antony Booth - Compress-Archive has a problem if the path contains spaces, even if you put it in double quotes. See here: https://stackoverflow.com/questions/18180060/how-to-zip-a-file-using-cmd-line/64475079#comment134664312_64475079 – dcp Jun 22 '23 at 13:43
5

You're near :)

First, the batch (%%variable) and Windows CMD (%variable) uses different variable naming. Second, i dont figure out how do you use zip from CMD. This is from Linux users i think. Use built-in zip manipulation is not like easy on Win, and even harder with batch scripting.

But you're lucky anyway. I got (extracted to target folder) zip.exe and cygwin1.dll from the cygwin package (3mb filesize both together) and start play with it right now.

Of course, i use CMD for better/faster testing instead batch. Only remember modify the %varname to %%varname before blame me :P

for /d %d in (*) do zip -r %d %d

Explanation: for /d ... that matches any folder inside. Only folder ignoring files. (use for /f to filesmatch) for /d %d in ... the %d tells cmd wich name do you wanna assign to your variable. I put d to match widh d (directory meaning). for /d %d in (*) ... Very important. That suposses that I CD to desired folder, or run from. (*) this will mean all on THIS dir, because we use /d the files are not processed so no need to set a pattern, even if you can get only some folders if you need. You can use absolute paths. Not sure about issues with relatives from batch. for /d %d in (*) do zip -r ... Do ZIP is obvious. (exec zip itself and see the help display to use your custom rules). r- is for recursive, so anyting will be added. for /d %d in (*) do zip -r %d %d The first %d is the zip name. You can try with myzip.zip, but if will fail because if you have 2 or more folders the second cannot gave the name of the first and will not try to overwrite without more params. So, we pass %d to both, wich is the current for iteration folder name zipped into a file with the folder name. Is not neccesary to append ".zip" to name.

Is pretty short than i expected when start to play with.

m3nda
  • 1,986
  • 3
  • 32
  • 45
  • Shouldn't you use `-rp`? Otherwise duplicate file names will clash, won't they? – ixe013 Dec 10 '13 at 05:47
  • as you say, when try to add identical filenames will clash, but... we are getting real files from real folders. There aren't any duplicate filename. We are putting each subfolder content into a zip named like the folder. No collission. I try with real folders into my system when starting to post :) – m3nda Dec 10 '13 at 06:54
  • THanks all for the responses and thanks erm3nda for the detailed explanation. All this helped me out. Thanks again. – user3085265 Jan 08 '14 at 01:51
4

Starting windows 10 build 17063, you can use TAR. MSDN link

For example, to create a zip file for a directory named folder XYZ that is in inside folder Reports, you can enter the following in the command prompt.

tar -cf XYZ.zip \Reports\XYZ
TechNerd
  • 91
  • 5
  • You have to specify a format and a compression algorithm, or else TAR will simply concatenate the source files to produce the target. TAR 3.5.2 on Windows 10 Build 19042 only supports [ustar | pax | cpio | shar] formats, and compression algorithms [gzip | bzip2 | xz | lzma]. Do you know of a way to get any of the PKZIP formats from this? – Forbin May 02 '22 at 22:04
3

This is the correct syntax for archiving individual; folders in a batch as individual zipped files...

for /d %%X in (*) do "c:\Program Files\7-Zip\7z.exe" a -mx "%%X.zip" "%%X\*"
Floern
  • 33,559
  • 24
  • 104
  • 119
1

I like PodTech.io's answer to achieve this without additional tools. For me, it did not run out of the box, so I had to slightly change it. I am not sure if the command wScript.Sleep 12000 (12 sec delay) in the original script is required or not, so I kept it.

Here's the modified script Zip.cmd based on his answer, which works fine on my end:

@echo off   
if "%1"=="" goto end

setlocal
set TEMPDIR=%TEMP%\ZIP
set FILETOZIP=%1
set OUTPUTZIP=%2.zip
if "%2"=="" set OUTPUTZIP=%1.zip

:: preparing VBS script
echo Set objArgs = WScript.Arguments > _zipIt.vbs
echo InputFolder = objArgs(0) >> _zipIt.vbs
echo ZipFile = objArgs(1) >> _zipIt.vbs
echo Set fso = WScript.CreateObject("Scripting.FileSystemObject") >> _zipIt.vbs
echo Set objZipFile = fso.CreateTextFile(ZipFile, True) >> _zipIt.vbs
echo objZipFile.Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
echo objZipFile.Close >> _zipIt.vbs
echo Set objShell = WScript.CreateObject("Shell.Application") >> _zipIt.vbs
echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
echo Set objZip = objShell.NameSpace(fso.GetAbsolutePathName(ZipFile)) >> _zipIt.vbs
echo if not (objZip is nothing) then  >> _zipIt.vbs
echo    objZip.CopyHere(source) >> _zipIt.vbs
echo    wScript.Sleep 12000 >> _zipIt.vbs
echo end if >> _zipIt.vbs

@ECHO Zipping, please wait...
mkdir %TEMPDIR%
xcopy /y /s %FILETOZIP% %TEMPDIR%
WScript _zipIt.vbs  %TEMPDIR%  %OUTPUTZIP%
del _zipIt.vbs
rmdir /s /q  %TEMPDIR%

@ECHO ZIP Completed.
:end

Usage:

  • One parameter (no wildcards allowed here):

    Zip FileToZip.txt

    will create FileToZip.txt.zip in the same folder containing the zipped file FileToZip.txt.

  • Two parameters (optionally with wildcards for the first parameter), e.g.

    Zip *.cmd Scripts

    creates Scripts.zip in the same folder containing all matching *.cmd files.


Note: If you want to debug the VBS script, check out this hint, it describes how to activate the debugger to go through it step by step.

Matt
  • 25,467
  • 18
  • 120
  • 187
0

Simple script Its convert all dump folder and subfolder files in desktop as backup.zip

write this below line in backup.bat and execute

"C:\Program Files\7-Zip\7z.exe" a -tzip "C:\Users\shris\Desktop\backup.zip" -r "C:\Users\shris\Desktop\dump\*" -mx5
0

Late to the party, but I wanted to add on to another proposed answer that recommended tar, but the output zip archive could not be read because the format was wrong. In order to resolve this, one must include the argument --archive zip. Here is an example:

tar -cf path\to\target.zip --format zip path\to\source

Also, if you are using tar from the command line then you can use argument -a instead of --format, and tar will automatically use the correct format based on the output file's extension ("zip" in this case). Unfortunately, -a is not available when using tar in a batch script.

See other format options here from FreeBSD.

MasterChef
  • 45
  • 1
  • 1
  • 9
-1

This is link by Tomas has a well written script to zip contents of a folder.

To make it work just copy the script into a batch file and execute it by specifying the folder to be zipped(source).

No need to mention destination directory as it is defaulted in the script to Desktop ("%USERPROFILE%\Desktop")

Copying the script here, just incase the web-link is down:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET sourceDirPath=%1
IF [%2] EQU [] (
  SET destinationDirPath="%USERPROFILE%\Desktop"
) ELSE (
  SET destinationDirPath="%2"
)
IF [%3] EQU [] (
  SET destinationFileName="%~n1%.zip"
) ELSE (
  SET destinationFileName="%3"
)
SET tempFilePath=%TEMP%\FilesToZip.txt
TYPE NUL > %tempFilePath%

FOR /F "DELIMS=*" %%i IN ('DIR /B /S /A-D "%sourceDirPath%"') DO (
  SET filePath=%%i
  SET dirPath=%%~dpi
  SET dirPath=!dirPath:~0,-1!
  SET dirPath=!dirPath:%sourceDirPath%=!
  SET dirPath=!dirPath:%sourceDirPath%=!
  ECHO .SET DestinationDir=!dirPath! >> %tempFilePath%
  ECHO "!filePath!" >> %tempFilePath%
)

MAKECAB /D MaxDiskSize=0 /D CompressionType=MSZIP /D Cabinet=ON /D Compress=ON /D UniqueFiles=OFF /D DiskDirectoryTemplate=%destinationDirPath% /D CabinetNameTemplate=%destinationFileName%  /F %tempFilePath% > NUL 2>&1

DEL setup.inf > NUL 2>&1
DEL setup.rpt > NUL 2>&1
DEL %tempFilePath% > NUL 2>&1
Abhijeet
  • 8,561
  • 5
  • 70
  • 76
  • @ChamindaBandara, not what's the issue you are facing. I had tested this code on Windows 10. – Abhijeet Sep 27 '18 at 04:27
  • I ran the script inside a folder but nothing won't happened. – Chaminda Bandara Sep 27 '18 at 07:08
  • It kinda works (on Windows 10), but puts the archive on your desktop as ".zip" with no name. The built in ZIP doesn't understand the file but you can parse the resulting file using 7zip.. so it "kinda" works. Probably just needs some logical improvements and really it just uses the MAKECAB feature, which is clever I think. Anyways, best. – jacktrader Mar 05 '19 at 00:11