0

We have almost 2.5 million files of archive data that need to be organized according to the year in which they were created. We need to move files from their current folder on our NAS to another folder that is the year in which the file was created. The destination folder is a four character year value (2003, 2004, etc.). The filename is in the format AAAAAAAAA_YYYYMMDD_BBBBBB.dfa where YYYY is the year value in which the file was created. The file extension can be either .dfa or .dfc. Folders for the appropriate year already exist, but files that are incorrectly placed in the wrong year must be moved to the appropriate year folder.

I need a batch file that will move files from their current location to the appropriate year folder on the NAS, but do not know how to parse the year value from the filename to move the file to the proper year.

Could someone help me with a batch file or script that will do this?

1 Answers1

0

The following batch file walks through the root directory given by variable ROOT recursively and moves files into the appropriate year-folder:

@echo off

rem specify the root directory here (the directory containing the year folders):
set ROOT="."
rem define the file search pattern(s) here:
set PATTERNS="*.dfa" "*.dfc"
rem set this to non-empty for flexible file name parsing:
set FLEXMODE=
rem set this to a log file path
rem (log contains date/time, TRUE/FALSE for move success/failure, source, dest.):
set LOGF=".\movement.log"

setlocal EnableDelayedExpansion

rem loop through every file recursively
for /R %ROOT% %%F in (%PATTERNS%) do (
  rem extract parent folder name
  set PARENT=%%~dpF
  set PARENT=!PARENT:~-5,4!
  rem parse file name, extract year portion
  if defined FLEXMODE (
    for /F "tokens=2 delims=_" %%N in ("%%~nF") do (
      set YEAR=%%N
      set YEAR=!YEAR:~,4!
    )
  ) else (
    set YEAR=%%~nF
    set YEAR=!YEAR:~10,4!
  )
  rem check whether parent folder name equals year portion of file name
  if not "!PARENT!"=="!YEAR!" (
    rem move file if not in appropriate year folder (no overwrite)
    if not exist "%%~dpF..\!YEAR!\%%~nxF" (
      move /Y "%%~fF" "%%~dpF..\!YEAR!" > nul
      echo %DATE%, %TIME%    TRUE    "%%~fF"    "%%~dpF..\!YEAR!\%%~nxF"
    ) else (
      echo %DATE%, %TIME%    FALSE   "%%~fF"    "%%~dpF..\!YEAR!\%%~nxF"
    )
  ) >> %LOGF%
)

endlocal

Pre-Requisites:

  • set the variables in the beginning block accordingly:
    • ROOT: full root directory path;
    • PATTERNS: file pattern(s) to use for searching;
    • FLEXMODE: set this to a non-empty value if the AAAAAAAAA portion in your file names AAAAAAAAA_YYYYMMDD_BBBBBB.* may vary in length; in such cases, the first underscore _ is used to find the year YYYY; otherwise (empty value), the year is extracted by its position;
    • LOGF: path and name of a log file that will contain four columns (separated by 4 spaces): date and time, TRUE/FALSE to indicate success/failure, source file path, destination file path; files that are already placed correctly are not logged here;
  • the year folders are placed as immediate childs of the given root directory;
  • all files are located within a year-folder (wrong or right year);
  • you have sufficient access privileges within the entire root directory tree;
  • for script testing, place rem in front of the move command and review the log file;

Explanation:

  • core element is the for /R loop that walks through the directory hierarchy;
  • for each file, variable PARENT is set to the immediate parent directory name (the ~dp modifier in %%~dpF extracts drive and path, including a trailing backslash);
  • depending on FLEXMODE, the year YYYY portion is extracted from the file name (if FLEXMODE is defined, a for /F loop is used to parse the file name and split it into underscore-delimited tokens, the first 4 characters of the second token are the year, stored in YEAR; if FLEXMODE is empty, 4 characters at offset 10 are extracted and stored in YEAR);
  • next the extracted YEAR is checked against the parent directory name PARENT; if equal, do nothing else and go to next for /R iteration; otherwise, the file is moved but only if the destination does not yet exist;
  • finally, a log string is generated and returned by echo, which is then redirected to the specified log file;
  • for modifying variable values (PARENT, YEAR) and using them within a loop structure (or also , other code blocks), delayed expansion is required;
Community
  • 1
  • 1
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • Thank you for responding so quickly. I will give the script a try. – Dale Franks Sr Aug 04 '15 at 19:39
  • Tested the script. It ran correctly. Am now applying it to one of the year folders to move files that may be in an incorrect folder. Thank you for your help!!! – Dale Franks Sr Aug 04 '15 at 20:56
  • You're welcome! for the script to run correctly, please check the pre-requisites I mentioned; I recommend to put a `rem ` before the `move` statement temporarily and check the log file to see whether everything behaves as expected... – aschipfl Aug 04 '15 at 20:59
  • I tested the script before I ran it against the production archive folders. It moved test files into the proper folders. Have run the script against three production archive folders. Log files are showing the script is moving files from incorrect folders to the correct ones. The script is working like a charm. Thank you again for your help. – Dale Franks Sr Aug 06 '15 at 12:34
  • Great! if my answer really helps you, consider to accept it; thanks! – aschipfl Aug 06 '15 at 14:40