Search code examples
parametersbatch-fileziparchivesubdirectory

Batch-compressing/archiving files within subcategories (files have to be in the root)


I've been searching for a while now to archive a LOT of photographs in different directories into seperate zip-archives. With no luck so far. How come? I have some specific requests;

The directory-structure:

YEAR => Category (12 directories, the same for each year) => Each Category has it's own events => Each event has it's own pictures. For example:

2013\

--------Category1\

--------Category2\

--------Category3\

-----------------------Subcategory1\

--------Category4\

--------Category5\

--------Category6\

-----------------------Subcategory1\

-----------------------Subcategory2\

------------------------------------------Photograph1.jpg

------------------------------------------Photograph2.jpg

--------Category7\

and so on...

Year: 7 directories Subcategories in each year-folder: 12 Sub-subcategory in each Subcategory folder: 100-200 Photographs inside all folders: 70GB, not sure how many files exactly.

My question

I would like to create individual zip-archives for each subcategory. Here's the catch: The zip archives must fulfil to 2 requests:

1) The photographs have to be placed in the root of the zip-archive. When you open up a zip-archive, the first thing you have to see are photographs. No (sub)directories.

2) If possible, the zip-archives have to be limited to a filesize of 150mb each. So even if a subcategory contains 200mb of photographs, the script/parameters have to set limits to the filesize. Not just 'splitting up' a 200mb zip-archive, but really make 2 seperate zip-archives. One being 150mb in size, the other 50mb.

Would this be possible to do? There are a lot of ways to archive files by scripts and I did try a few, but none of them seem to work the way I want it to work ;-)

So... the zip-archives have to be put in the same sub-category besides the photographs, can't be any bigger then 150mb each and have to understand what files have to be zipped (the content of sub-categories within a sub-category within the year-category).

Thanks! :)


Solution

  • Here you go. Save this with a .vbs extension. I haven't tested it thoroughly, but I think it should work. For each directory that contains files, it will zip those files to an archive within the same containing directory.

    Oh, and welcome to SO! Since you are new, you might want to check this link.

    ' archive_limit.vbs
    ' usage: cscript archive_limit.vbs (directory, optional)
    ' If directory is not supplied, traverse subdirectories of current
    
    on error resume next
    if WSH.arguments.count = 0 then
        dir = left(WSH.ScriptFullName,(Len(WSH.ScriptFullName))-(len(WSH.ScriptName)))
    else
        dir = WSH.arguments(0)
        if not Right(dir, 1) = "\" then
            dir = dir & "\"
        end if
    end if
    
    set fso = createobject("scripting.filesystemobject")
    set shl = createobject("shell.application")
    
    EnumFolders(fso.GetFolder(dir))
    
    WSH.Quit 0
    
    Sub EnumFolders(fFolder)
        Set objFolder = fso.GetFolder(fFolder.Path)
        Set colFiles = objFolder.Files
        zipnum = 1
        For Each objFile in colFiles
            zipfile = fFolder.Path & "\archive" & zipnum & ".zip"
    
            If fso.FileExists(zipfile) Then
                projected = fso.GetFile(zipfile).Size + objFile.Size
                if projected >= 157286400 Then
                    zipnum = zipnum + 1
                    zipfile = fFolder.Path & "\archive" & zipnum & ".zip"
                End If
            End If
    
            if not fso.FileExists(zipfile) Then
                set zip = fso.createtextfile(zipfile)
                zip.write "PK" & chr(5) & chr(6) & string(18, chr(0))
                zip.close
            End If
    
            If Not LCase(fso.GetExtensionName(objFile.name)) = "zip" Then
                ' uncomment the following line to log progress to the console
                ' WSH.Echo "Zipping " & fFolder.Path & "\" & objFile.name & " to " & zipfile
                zipitems = shl.namespace(zipfile).items.count
                shl.namespace(zipfile).copyhere(fFolder.Path & "\" & objFile.name)
                do until shl.namespace(zipfile).items.count > zipitems
                    WSH.Sleep 100
                loop
            End If
    
        Next
    
        For Each Subfolder in fFolder.SubFolders
            EnumFolders(Subfolder)
        Next
    End Sub