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;