简体   繁体   中英

Batch Script to Organize Files by Date

I am trying to organize all files (and directories) on the T: drive into two directories: Pre2010 and PostAnd2010 . The files should be organized based on their last modified time--so if file T:\\dirA\\fileA1 has the timestamp 12/28/2015 03:42pm it should be moved to T:\\PostAnd2010\\dirA\\ , maintaining the same file name. Also, if the file T:\\dirA\\fileA2 has the timestamp 1/13/2009 12:23am it should be moved to T:\\Pre2010\\dirA\\ with the same filename. So the new Pre2010 and PostAnd2010 directories should maintain the same directory structure as the T: drive previously had, but splitting the files by date.

I don't really have any experience writing batch files, but I have been trying! Here's my code so far:

@ECHO OFF
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

chdir /d T:

FOR /r %%i IN (*) do (

   FOR %%a in (%%i) do set FileDate=%%~ta
   set year=!FileDate:~6,4!

   if !year! LSS 2010 (
      REM Move to T:\Pre2010\<filepath>
      echo !year! is before 2010
   ) else (
      REM Move to T:\PostAnd2010\<filepath>
      echo !year! is 2010 or after
   )

   REM echo !year!
   pause
)

echo Done.
pause

This seemed to be working okay, but then I noticed that the year would occasionally be printed as ~6,4 instead of the actual year. I checked the timestamps of the files that were causing the issue, but nothing seemed strange about them. I am not sure why FileDate and year are blank on some files. I want to figure out this issue before I finish the moving the files portion.

Any help would be greatly appreciated! Thanks!

Use ROBOCOPY

robocopy /? for help, particularly:

/MAXAGE:n :: MAXimum file AGE - exclude files older than n days/date.
/MINAGE:n :: MINimum file AGE - exclude files newer than n days/date.
/MAXLAD:n :: MAXimum Last Access Date - exclude files unused since n.
/MINLAD:n :: MINimum Last Access Date - exclude files used since n.
         (If n < 1900 then n = n days, else n = YYYYMMDD date).

Use /L to see what robocopy will do.

Use /MIR to do the actual move.

Copy old files

rem /L to see what it does
robocopy l:\test\fileage\all l:\test\fileage\old /MINAGE:20151002 /L /MIR

or

rem /MIR to actually move the files
robocopy l:\test\fileage\all l:\test\fileage\old /MINAGE:20151002 /MIR

Copy new files

rem /L to see what it does
robocopy l:\test\fileage\all l:\test\fileage\new /MAXAGE:20151002 /L /MIR

or

rem /MIR to actually move the files
robocopy l:\test\fileage\all l:\test\fileage\new /MAXAGE:20151002 /MIR

Creating test files...

What I did was copy c:\\windows\\system32\\nv*.dll l:\\test\\fileage\\all

This gave me a small list of files that had a visible date break before/after the 20151002 date.

You should be able to adapt easily to your directory names.

Kory Gill's answer leads you to the easiest and most efficient way for your task, using robocopy :

rem Remove the `/L` switch to actually move items:
robocopy "T:\" "T:\Pre2010"     "*.*" /L /E /MOVE /XD "Pre2010" "PostAnd2010" /MINAGE:20100101
robocopy "T:\" "T:\PostAnd2010" "*.*" /L /E /MOVE /XD "Pre2010" "PostAnd2010" /MAXAGE:20100101

However, I want to rely on your code.


You used a for /R loop iterating through all items in the root of T: . The destination directories Pre2010 and PostAnd2010 are also located there. Since you are moving files, you are manipulating the directory tree which is enumerated by for /R . As per this post , for /R does not enumerate the entire directory tree before iterating, so unexpected results may occur. To overcome this, use the dir /B /S command and parse its output by a for /F loop instead, so the entire directory tree is enumerated before the loop actually starts to iterate through all the items. See the following code:

@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "YEAR=2010"
set "OLDDIR=Pre2010"
set "NEWDIR=PostAnd2010"

chdir /D "T:\"

for /F "eol=| delims=" %%F in ('
    dir /S /B /A:-D "*.*"
') do (
    set "FILEDATE=%%~tF"
    rem The following depends on the region settings:
    if "FILEDATE:~6,4!" LSS %YEAR% (
        xcopy /L "%%~fF" "%%~dF\%OLDDIR%%%~pF"
    ) else (
        xcopy /L "%%~fF" "%%~dF\%NEWDIR%%%~pF"
    )
)
call :CLEANUP

endlocal
exit /B

:CLEANUP
ECHO del /Q "*.*"
for /F "eol=| delims=" %%D in ('
    dir /S /B /A:D "*.*"
') do (
    set "PATHNAME=%%~fD"
    if "!PATHNAME:%OLDDIR%=!"=="!PATHNAME!" (
        if "!PATHNAME:%NEWDIR%=!"=="!PATHNAME!" (
            ECHO rmdir /S /Q "%%~fD"
        )
    )
)
exit /B

Besides the replacement of for /R by for /F and dir /B /S , this is what I did:

  • put the two destination directories and the year into variables OLDDIR , NEWDIR and YEAR , resp.;
  • removed interim variable YEAR and queried FILEDATE:~6,4 immediately;
  • replaced move by xcopy , because move moves files only, so there were only empty directories left finally; so I use xcopy and delete the source files and directories later; remove the /L switch from both xcopy commands to actually copy anything, otherwise it just lists what would be copied;
  • removed some echo and pause statements for debuggung;
  • after the for /F loop, jump to :CLEANUP subroutine;
  • introduced a :CLEANUP routine that deletes everything in the source T:\\ except the two destination directories, of course; at first, files in the root dierctory are deleted, then the source directory tree is removed; remove the upper-case ECHO s (twice) to actually delete any source files and directories, otherwise it just outputs what would be deleted;

I appreciate the help from the two answers that I received! They both helped me come to a final solution. I decided to use robocopy instead of the looping I was originally using for simplicity. I ran the script on the drive, which had around 50gb of data and it took a couple hours. I'm slightly concerned by robocopy's output because it reports skipped files and directories; it might be fine though. Here's what I ended up using:

@echo off

chdir /d T:

robocopy T: "T:\Pre2010" /MINAGE:20091231 /S
pause

robocopy T: "T:\PostAnd2010" /MAXAGE:20100101 /S
pause

echo Done!
pause

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM