Link to home
Start Free TrialLog in
Avatar of arundelr
arundelr

asked on

Script to move files based on age and name

Hi,

I am looking to have a simple script which will move files over 24 hours since modified date into a different directory.  

The only other thing is that the file name mask will determine which directory the file is moved into

i.e. if the file is called docu1_3333   I want to day all files docu1* move into c:\testing\moveover24h\docu1
and then use differennt file masks for different folders.  

I did start to try something in VBScript but that did niot work out (attached)  I am quite happy to use a dos batch script of VB script - which ever is simplest

 
Dim fso, startFolder, OlderThanDate
 
Set fso = CreateObject("Scripting.FileSystemObject")
startFolder = "C:\testing\Invoice_over_24h\comms\" ' folder for source data
TargetFolder = "C:\testing\Invoice_over_24h\target_dsg\" ' folder for target data
OlderThanDate = DateAdd("d", -1, Date)  ' 1 day old
 
DeleteOldFiles startFolder, OlderThanDate
 
Function DeleteOldFiles(folderName, BeforeDate)
   Dim folder, file, fileCollection, folderCollection, subFolder
 
   Set folder = fso.GetFolder(folderName)
   Set fileCollection = folder.Files
   For Each file In fileCollection
      If file.DateLastModified < BeforeDate 
	  Then objFSO.MoveFile strFiles , TargetFolder & "\" & strFiles.Name
      End If
   Next
 
    Set folderCollection = folder.SubFolders
    For Each subFolder In folderCollection
       DeleteOldFiles subFolder.Path, BeforeDate
    Next
End Function

Open in new window

Avatar of andyleroo
andyleroo

I hope I can help you with this.  For the code below I made the assuption that all the files you are moving will have the underscore character '_' somewhere in the file name and that you want the files putting in a directory with the name of what is to the left of this character.  For example, the file 'docu1_3333.txt' would go into the target folder in a subfolder called 'docu1'

Please give it a try - please note it is not very robust as is, if you were to use it for real you may want to include some error checking.  One example is that in its current form, if you try to copy a file from the source to the target that already exists it will fail.

Paste the script into a file, 'processfiles.vbs' for example and double click to run or run using the cscript.exe command.

PLEASE make sure the source and destination directories are set as you need them - could be nasty ;o)

Option Explicit
 
Dim objFileSystemObject, strStartFolder, strTargetFolder, dtmADayAgo
 
'** Main - Start
 
Set objFileSystemObject = CreateObject("Scripting.FileSystemObject")
 
strStartFolder = "C:\testing\Invoice_over_24h\comms"    ' folder for source data
strTargetFolder = "C:\testing\Invoice_over_24h\target_dsg"  ' folder for target data
dtmADayAgo = DateAdd("d", -1, Date)
 
processFiles strStartFolder
 
'** Main - End
 
'** Procs - Start
 
' Process the files (and files in subfolders) of the provided source directory
Sub processFiles(strFolderName)
  Dim objRootFolder, colFolders, objFolder, colFiles, objFile
 
  Set objRootFolder = objFileSystemObject.GetFolder(strFolderName)
  Set colFiles = objRootFolder.Files
  Set colFolders = objRootFolder.Subfolders
 
    ' Process files in the current folder
  For Each objFile In colFiles
      If olderThanADay(objFile.DateLastModified) Then
          objFile.Move(createDirectory(objFile.Name) & "\" & objFile.Name)
      End If
  Next
 
  'Process subfolders
  For Each objFolder In colFolders
    processFiles objFolder.Path
  Next
End Sub
 
' Determine if a date is older than one day
' Return True if it is, else false
Function olderThanADay(dtmModifiedDate)
  If dtmModifiedDate < dtmADayAgo Then
    olderThanADay = True
  Else
    olderThanADay = False
  End If
End Function
 
' Create a directory in the target directory in which to put the file
' Use the part of the file name to the left of the '_' for the directory name
' Return the path the file should be moved to
Function createDirectory(strFileName)
  Dim strDirName
 
  strDirName = (Split(strFileName, "_"))(0)
  
  ' Create the folder if it doesn't exist
  If Not objFileSystemObject.FolderExists(strTargetFolder & "\" & strDirName) Then
      objFileSystemObject.CreateFolder(strTargetFolder & "\" & strDirName)
  End If
  
  createDirectory = strTargetFolder & "\" & strDirName
End Function

Open in new window

Avatar of arundelr

ASKER

Hi,

Thanks very much. Unfortunately the assumption is not always going to be true.

It doesn't really need to put it in a sub folder, what it needs to do is explicitly say that files called docu1_*  will go into the target folder (if fits in age range) and then it would ignore any other files in the source folder.

Is it possible to adjust with that in mind ?

many thanks

Rob
OK - You only want to move files that start 'docu1_' and only if they are older than 24 hrs.

If this is the case then we can remove the function createDirectory as it's not really needed and maybe create one that checks if the file sould be copied using the criteria 'filename begins with docu1_'

The modified script is below.

Option Explicit
 
Dim objFileSystemObject, strStartFolder, strTargetFolder, dtmADayAgo
 
'** Main - Start
 
Set objFileSystemObject = CreateObject("Scripting.FileSystemObject")
 
strStartFolder = "C:\testing\Invoice_over_24h\comms"          ' folder for source data
strTargetFolder = "C:\testing\Invoice_over_24h\target_dsg"    ' folder for target data
dtmADayAgo = DateAdd("d", -1, Date)
 
processFiles strStartFolder
 
'** Main - End
 
'** Procs - Start
 
' Process the files (and files in subfolders) of the provided source directory
Sub processFiles(strFolderName)
    Dim objRootFolder, colFolders, objFolder, colFiles, objFile
 
    Set objRootFolder = objFileSystemObject.GetFolder(strFolderName)
    Set colFiles = objRootFolder.Files
    Set colFolders = objRootFolder.Subfolders
 
    ' Process files in the current folder
    For Each objFile In colFiles
        If olderThanADay(objFile.DateLastModified) Then
            If checkFileName(objFile.Name, "docu1_") Then
                objFile.Move(strTargetFolder & "\" & objFile.Name)
            End If
        End If
    Next
 
    'Process subfolders
    For Each objFolder In colFolders
        processFiles objFolder.Path
    Next
End Sub
 
' Determine if a date is older than one day
' Return True if it is, else false
Function olderThanADay(dtmModifiedDate)
    If dtmModifiedDate < dtmADayAgo Then
        olderThanADay = True
    Else
        olderThanADay = False
    End If
End Function
 
' Check if a file name begins with the specified string
' Returns True if it does else False.
Function checkFileName(strFileName, strCompareString)
    Dim blnReturn
    
    blnReturn = False
    
    If Len(strCompareString) <= Len(strFileName) Then
        If UCase(Left(strFileName, Len(strCompareString))) = UCase(strCompareString) Then
            blnReturn = True
        End If
    End If
    
    checkFileName = blnReturn
End Function

Open in new window

Woo hoo - I tried and thats great ;)  - sorry Im not so hot on VBS

The only thing I noticed is that its not taking into account the time stamp on the file.

i.e. I had a failed last modified 18-03-2008 09:09  and that one would not get moved by this script even though its now 19-03-2008 15:06 (so long as it was passed 09:19 today then that file was really 25hours old and should have been moved)

Is it possibel to include that somehow?

Thanks for all your help!

Here's a batch script to do what you'd like.  I've commented it as much as I thought needed in case you need to augment it.

If you have any questions let me know, but the thing should just work.

I'm going to bed now. :)
@echo off
rem archive.bat will archive files older than a set number of days
rem Files set to be archived must have an underscore in the filename.
rem Created by forrestoff, 03/22/2008
 
rem Below is to set how old the file is before it's archived
rem For example:
rem set archive_days = 1
rem will move all files older than 1 day to a different directory
rem rooted in the path set by the archive_path variable
 
set /a archive_days=1
 
set    archive_path="c:\testing\moveover24h\"
 
rem ------------------------------------------------------------------------
 
rem batch setup
del filelist2 2>nul & del filelist 2>nul & del movelist 2>nul
 
rem modify this file so that it doesn't get archived.
echo. >>archive.bat
 
setlocal EnableDelayedExpansion
 
rem get file list
for /f "tokens=*" %%i in ('dir/b/a-d') do echo %%~ti %%i >> filelist
 
rem type filelist
 
rem Find how old file is (in minutes) since 2000.
rem If file is older than 2000, process will still work.
 
for /f "tokens=1,2,3,4,5,6,7* delims=/: " %%a in (filelist) do (
    if %%f==PM (
        set /a hour=1%%d+12-100
        ) else (
        set /a hour=1%%d-100
        )
 
    rem set minutes since year 2000
    rem format yyyymmddhhmm
    rem 525,600 min/yr
    rem  45,360 min/mo
    rem   1,140 min/day
    rem      60 min/hr
 
    set /a year = %%c-2000
 
    set /a min2000 = !year!*525600+%%a*45360+%%b*1140+60*!hour!+%%e
 
    @echo !min2000! %%g >>filelist2
    )
 
rem type filelist2
 
rem Calculate current minutes-since-year 2000 minus a archive time
 
set /a archtime = !archive_days!*1140
 
for /f "tokens=1,2,3,4,5,6,7,8 delims=/: " %%m in ('echo %date% %time%') do (
    set /a year = %%p-2000
    set /a deadline=!year!*525600+%%n*45360+%%o*1140+%%q*60+%%r-!archtime!
    rem @echo !deadline!
    )
 
rem Compare file timestamp with current time minus archive_days*1140 (there are
rem 1140 minutes in 1 day--did you know?)
 
cd.>movelist
for /f "tokens=1,2" %%v in (filelist2) do (
    if %%v LSS !deadline! @echo %%w >> movelist)
 
for /f "tokens=1,2* delims=_" %%x in (movelist) do mkdir %archive_path%%%x 2>nul & move /y %%x_%%y %archive_path%%%x 2>nul& echo file %%x_%%y moved to %archive_path%%%x
 
 
rem Housekeeping
del filelist2 2>nul & del filelist 2>nul & del movelist 2>nul
 
echo Archive Complete.

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of andyleroo
andyleroo

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
I need the same VB script, but changed to 180 days with the file name looking like this 07_4-43-39 PM_
COuld anyone help wiht that?