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;