Link to home
Start Free TrialLog in
Avatar of Simuser
SimuserFlag for United States of America

asked on

zipping files based on date stamp.

I am trying to write a .bat file that will zip files based on modified date, and sorted into monthy zip files.
I have multiple directories that contain years of files.
I would like the .bat file to zip those files based on the month and year modified.

The output would be 062008.zip for all the files modified in the sixth month of 2008, 072008.zip for the files modified in the seventh month of 2008, and so on.

At the end, I would like to delete each of the files that are now zipped.
This is on Windows Server 2008 r2.
I currently use 7zip and doing it by hand, but this process will take months to complete.

Any suggestions?

Avatar of TheGorby
TheGorby
Flag of United States of America image

Do you need to retain the folder structure, or do you want the archive to only contain files?

If you don't need folders then I can write a quick script with AutoIT(http://www.autoitscript.com/site/autoit/) if you're interested.
Avatar of Simuser

ASKER

I have no problem running the script on each directory manually, so directory structure isn't too important.
Some directories have 50-75 k of files in them, to a script is a must at this point.
Avatar of Bill Prew
Bill Prew

Give this BAT file a try, add as many source directories as you need.  We'll work the deletes if the ZIP part works okay.

@echo off
set ZipDir=c:\temp

call :DoZip "c:\dir1"
call :DoZip "c:\dir2"
exit /b

:DoZip
  for %%A in ("%~1\*.*") do (
    for /f "tokens=1,3 delims=/ " %%B in ("%%~tA") do (
      7z a -tzip %%B%%C.zip -o"%ZipDir" "%%A"
    )
  )
  exit /b

Open in new window

~bp
SOLUTION
Avatar of TheGorby
TheGorby
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Simuser

ASKER

Thanks for your attempt. I must not have made the correct request.
My problem lays in having years of files in directories.
What I would like to do is zip up those files sorted into monthy files.
For example:
all files modified in the month of June 2008 to be put into a zip file that is named 062008.zip
for the files modified in the month of July 2008 to be put into a zip file that is named 072008.zip
In the end, I would have a zip file for each month in every year.

I wanted to avoid that, as when they ever have to be retreived, I'm stuck back in the same situtation, with 10k plus files in the directory.

As for the script that you wrote, all it's doing is adding every file into one BIG zip file dated 022011.zip

As a side note, I did find a vbs script that results in what I want the end result to be, BUT it's using the windows compress feature which makes it really slow. Compressing one file every 20-40 seconds just isn't going to cut it.
https://www.experts-exchange.com/questions/26103961/Compress-Txt-Files-per-month-Batch-or-Vbscript.html

Do you think we could build a batch file that could emulate the results of this?

Incase I didn't say it, thanks to all you that are helping me!
I forgot to add the steps for compiling my script; first of all you'll need to download and install AutoIT from http://www.autoitscript.com/site/autoit/downloads/

The computer you install AutoIT on will be the one you use to compile the script. Just copy/paste the code from my other post into AutoIT's include script editor, save it anywhere (as an .AU3 file), press F7, and now you'll have an executable version that can be run from any computer even if it doesn't have AutoIT installed on it. The EXE will be saved to the same directory you saved the .AU3 file to.
Avatar of Simuser

ASKER

Thanks for your attempt. I must not have made the correct request.
My problem lays in having years of files in directories.
What I would like to do is zip up those files sorted into monthy files.
For example:
all files modified in the month of June 2008 to be put into a zip file that is named 062008.zip
for the files modified in the month of July 2008 to be put into a zip file that is named 072008.zip
In the end, I would have a zip file for each month in every year.


As for the script that you wrote, all it's doing is adding every file into one BIG zip file dated 022011.zip
I wanted to avoid that, as when they ever have to be retrieved, I'm stuck back in the same situation, with 10k plus files in the directory.

As a side note, I did find a vbs script that results in what I want the end result to be, BUT it's using the windows compress feature which makes it really slow. Compressing one file every 20-40 seconds just isn't going to cut it.
https://www.experts-exchange.com/questions/26103961/Compress-Txt-Files-per-month-Batch-or-Vbscript.html

Do you think we could build a batch file that could emulate the results of this?

Incase I didn't say it, thanks to all you that are helping me!
Avatar of Simuser

ASKER

Sorry about the double post, I was just trying to edit my response.... LOL
Did you give my BAT script a try, or was that not of interest?

~bp
Avatar of Simuser

ASKER


As of 12:13pm EST
There seems to be a lag on the forums for me...
@ Billprew, I processed your script, and my comments are above. It just created one big file with toda'ys date.

@ The Gorby, I just discovered your post, and installing the AutoIT complier as I write this.
I will get back with you on the results.

Avatar of Simuser

ASKER

@TheGorby

I keep getting a error. It's kinda random when I get it. The first time I ran the program, it crashed on the first month. The second time it crashed with an "no file or no permissions to access the file"
The third time, it crashed on the fifth month.
The first and third times it crashed, it threw this error:

Line 811 (File "C:\users\administrator\documents\directory_zipper.exe"):
Error: Object referenced outside a "With" statement.


1. Are you sure you have full permissions to all the files you're attempting to archive?
2. Are you sure you downloaded the latest version of AutoIT (v3.3.6.1)?

If the answer to both of those is Yes, then can you try running the program from a Windows XP or Windows Server 2003 computer?

Also please check to make sure ou have the file 'zipfldr.dll' in your system32 folder.
I just ran the script and it worked like a charm (it throw off a dialog when there was nothing in the zip file asking if I wanted to remove the empty zip file).  Thank you as I am having this problem with old files as well (I used use a tcsh command to run through unix directories, but the commands on windows don't stack up).
I forgot to sat I was running it from an XPSP3 box and used the latest version of AutoIT.
That must be it then, I'm on XP Pro SP3 as well. I imagine I could get it working on a Vista/Win7 machine, but I have none to test on :(

It shouldn't matter what Windows OS the files you're trying to archive are stored on, the big issue is what machine the program is being run on. I suspect Windows Server 2003 would work as well.

If you don't have an XP box to run from, the only thing I can think of is to add a line at the beginning of the script that lets AutoIT play nice with UAC; insert the following line at the very beginning:

#RequireAdmin

That should prompt you to allow the program to run with full system admin privilages.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
billprew, maybe I'm missing something but I would swear your 2 code posts are the exact same... I mention it because I'd be interested in a batch solution as well.
Yes, it was a very small miss on my part, but had important consequences.  Notice that this line:

      7z a -tzip %%B%%C.zip -o"%ZipDir" "%%A"


was missing one % symbol, and needed to be changed to:

     7z a -tzip %%B%%C.zip -o"%ZipDir%" "%%A"

~bp
Avatar of Simuser

ASKER

@billprew
Just wanted to let you know, I almost pee'ed my pants when I ran this code! It's almost exactly what I wanted. But I'm making it work regardless.
The only thing I'm changing is the first "call :dozip" line with the directory I want zipped.
When I run it, it doesn't really use the" set ZipDir=c:\temp" as the destination directory, but instead it uses the directory it was called from.
So in my case, I run it from a the directory "f:\zipper" and it process's all the files from the first "call :dozip" (z:\example\two) into the the "f:\zipper" directory.
I still need to go back into the   "call :dozip" (z:\example\two) to delete all the files, but at this point, I'm ok with doing it manually.
As a side note, I don't change the second "call :dozip" because I"m not sure if it will add the second directory files to the first "call :dozip" files.

If I had a wish list, I would like for it to delete the file that it just processed.
And if the wish list could be bigger, for it to ignore other zip files. This would allow for it to be ran in the directory that it is processing.

But even as it stands, I"m still a happy camper as this just reduced 2 months of work to 5 days!

THANK YOU !

Avatar of Simuser

ASKER

@TheGorby:
I found that your script works ok if the files it needs are on a local drive.
It still crashes mid script with the same errors that I posted before.
I tried running it from a XP machine, Vista, and Win7 machine. It seem to work best one of the Server 2008 R2 servers.

What I liked the best about your is that it would create the file right back in the directory that it was processing and delete the file it just processed. But when it crashes, you HAVE to manually put remaining  files for that month into that months file or else it deletes the old zip file and creates a new one.
Avatar of Simuser

ASKER

Although I have awarded the points already, I would really like to see this developed a bit more, as I know others what would like to implement this into daily backup process's
Oh don't worry I haven't given up... I've found that the problem was with the zip functions I found online, they weren't exactly... good. I found some new ones and am making adjustments to the script. Should have a working one later today that's without errors and works on XP, Vista and Win7 (and probably Server 2003 and later).
BAM! It's done, and works much much better than before. The new zip functions are credited to wraithdu(http://www.autoitscript.com/forum/topic/116565-zipau3-udf/) with a slight adjustment for my purposes.

Notes:
-Program no longer times-out on messages/prompts
-If the zip file for a given month and year already exists, matching files are simply added to it
-Still cannot use UNC paths (\\server\share) but if a share is mapped to a drive it will work (this is of course a bit slower than scanning files locally)
-The program accepts switches as follows: FileZipper.exe "C:\Source" year "C:\Destination"

Also, this time around the extra functions are too large to add to the main script and post here (apparent EE limit on length of code that can be posted). Instead, I've attached a file named "Zip-v2.txt". After downloading this file, rename it to "Zip-v2.au3" and save it to the Include directory of your AutoIT install (usually \Program Files\AutoIT3\Include).
#include <Zip-v2.au3>

Dim $output=@TempDir & "\output.tmp"

If $CmdLine[0]<>3 Then
	If $CmdLine[0]<>0 Then MsgBox(0+16+0+0+0,"Invalid Parameters","You have specified an invalid number of parameters." & @LF & @LF & "The correct format is: FileZipper.exe ""source"" year ""destination""")
	$parentfld=FileSelectFolder("Choose the parent folder to search in that you want to archive files from:","",6,"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")
	If @error=1 Then Exit
	$parentfld="""" & $parentfld & """"

	$yr=0
	While StringLen($yr)<>4
		$yr=InputBox("Select Year","Enter the 4-digit year you wish to archive:","","",250,130)
		If @error=1 Then Exit
		If StringLen($yr)<>4 Then MsgBox(0,"Invalid year","The year " & $yr & " is not a valid year. Please try again.")
	WEnd

	$zippth=FileSelectFolder("Choose the folder to save the archive(s) to:","",7,"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")
	If @error=1 Then Exit
	If StringInStr($zippth,"\",0,-1)<>StringLen($zippth) Then $zippth=$zippth & "\"
ElseIf $CmdLine[0]=3 Then
	$parentfld=$CmdLine[1]
	$parentfld="""" & $parentfld & """"
	$yr=$CmdLine[2]
	$zippth=$CmdLine[3]
	If StringInStr($zippth,"\",0,-1)<>StringLen($zippth) Then $zippth=$zippth & "\"
EndIf
If StringLen($yr)<>4 Then
	MsgBox(0,"Invalid year","The year " & $yr & " is not a valid year. Program will now quit.")
	Exit
EndIf

RunWait(@ComSpec & " /c DIR " & $parentfld & " /A:-D /B /S /T:W>" & $output)
$hnd=FileOpen($output,1)
FileWrite($hnd,"STOP")

ProgressOn("File Zipper","Archiving " & $yr & "...","Currently processing: ",200,200,16)
For $mo=1 To 12
	FileFlush($hnd)
	FileSetPos($hnd,0,0)
	If StringLen($mo)=1 Then $mo="0" & $mo
	ProgressSet(($mo-1)*8.33,"Currently processing: month " & $mo)
	If Not FileExists($zippth & $mo & $yr & ".zip") Then
		$zipname=_Zip_Create($zippth & $mo & $yr & ".zip")
	Else
		$exit=MsgBox(1+48+0+0+262144,"Archive already exists","The folder " & $zippth & " already contains an archive for month " & $mo & " in " & $yr & ";" & @LF & "any files found matching that date will be added to it.")
		If $exit=2 Then Exit
		$zipname=$zippth & $mo & $yr & ".zip"
	EndIf
	While 1
		$line=FileReadLine($hnd)
		If $line="STOP" Then ExitLoop
		If FileExists($line) Then
			$mod=FileGetTime($line)
			If $mod[0]=$yr Then
				If $mod[1]=$mo Then
					$actual=_Zip_AddItem($zipname,$line,"",28)
					Sleep(100)
					If FileExists($line) Then FileDelete($line)
					If $line<>$actual Then FileDelete($actual)
				EndIf
			EndIf
		EndIf
	WEnd
	$count=_Zip_Count($zipname)
	If $count=0 Then
		$delt=MsgBox(4+32+0+0+262144,"Archive empty - " & $mo & "/" & $yr,"There were no files for this month/year. Do you want to delete this empty archive?")
		If $delt=6 Then
			FileDelete($zippth & $mo & $yr & ".zip")
		Else
			$exit=MsgBox(1+64+0+0+262144,$mo & "-" & $yr,"There were " & $count & " files archived to file " & $zippth & $mo & $yr & ".zip." & @LF & "Select Cancel to stop further archiving.")
			If $exit=2 Then Exit
		EndIf
	Else
		$exit=MsgBox(1+64+0+0+262144,$mo & "-" & $yr,"There were " & $count & " files archived to file " & $zippth & $mo & $yr & ".zip." & @LF & "Select Cancel to stop further archiving.")
		If $exit=2 Then Exit
	EndIf
	ProgressSet($mo*8.33,"Currently processing: month " & $mo)
Next
ProgressOff()
FileClose($hnd)
FileDelete($output)
MsgBox(0+64+0+0+262144,"Finished - " & $yr,"All " & $yr & " files in " & $parentfld & " (and its subfolders) have been archived.")
Exit

Open in new window

It might help if I actually attached that file... here it is.
Zip-v2.txt
Hi All,

Thanks to everyone for the GREAT work that's already been done on this!

I have a couple of questions, if I may;

Is there a way to supress the message boxes, so I can automate & schedule this process?

Is there a way to stop the source files from being deleted?

Thanks in advance.