I started using batch commands last week and I've reached a real obstacle with a script I made.
What I want to do
Move a PDF file from C:\\Users\\JK\\Documents\\reports PDFs
into pre-made subfolders in the destination W:\\Departments\\QA\\cases
.
For example the script would move 2223 report.pdf
to W:\\Departments\\QA\\cases\\2201 - 2300\\2223
What I tried
I made a script based off the answer in this thread
cls
@pushd %~dp0
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=C:\Users\JK\Documents\reports PDFs"
set "DestDir=W:\Departments\QA\cases\"
for /F "eol=| delims=" %%A in ('dir /B /A-D-H "%SourceDir%\*.pdf" 2^>nul') do (
for /F "eol=| tokens=1" %%B in ("%%~nA") do (
for /D %%C in ("%DestDir%\%%B*") do move /Y "%SourceDir%\%%A" "%%C\"
)
)
endlocal
popd
pause
Where I am stuck
How could I add subfolders or account for them in the destination directory?
FYI, I also tried adding a wildcard symbol at the end of the destination directory by changing %DestDir%\\%%B
to %DestDir%\\*\\%%B*
.
I would probably accomplish the task with the following script (see all the explanatory rem
remarks):
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=C:\Users\JK\Documents\reports PDFs" & rem // (source directory; `.` or `` is current, `%~dp0.` is script parent)
set "_TARGET=W:\Departments\QA\cases" & rem // (target directory; `.` or `` is current, `%~dp0.` is script parent)
set "_SUBDIR=#" & rem // (set to non-blank value in order to create individual sub-directories)
set "_FMASK=????*.pdf" & rem // (pattern to match source files)
set "_DMASK=???? - ????*" & rem // (pattern to match target directories)
set "_FFIL1=^[0123456789][0123456789][0123456789][0123456789] .*\.pdf$" & rem // (filter 1 for source files)
set "_FFIL2=^[0123456789][0123456789][0123456789][0123456789]\.pdf$" & rem // (filter 2 for source files)
set "_DFIL1=^[0123456789][0123456789][0123456789][0123456789] - [0123456789][0123456789][0123456789][0123456789] .*$"
set "_DFIL2=^[0123456789][0123456789][0123456789][0123456789] - [0123456789][0123456789][0123456789][0123456789]$"
rem // Change into source directory:
pushd "%_SOURCE%" && (
rem // Iterate through all files matching the specified pattern and filters:
for /F "eol=| delims=" %%F in ('
dir /B /A:-D-H-S "%_FMASK%" ^| findstr /I /R /C:"%_FFIL1%" /C:"%_FFIL2%"
') do (
rem // Store full path of currently iterated file:
set "FILE=%%~fF"
rem // Extract the leading numeric part of the file name:
for /F "eol=| delims= " %%N in ("%%~nF") do (
rem // Store the numeric part:
set "NUM=%%N"
rem /* Remove any leading zeros from the numeric part of the file name, because
rem such cause the number to be unintentionally interpreted as octal: */
set /A "INT=0" & for /F "eol=| tokens=* delims=0" %%Z in ("%%N") do 2> nul set /A "INT=%%Z"
)
rem // Change into target directory:
pushd "%_TARGET%" && (
rem // Iterate through all directories matching the specified pattern and filters:
for /F "eol=| delims=" %%D in ('
cmd /V /C 2^> nul dir /B /A:D-H-S "!_DMASK:|=%%I!" ^| findstr /I /R /C:"%_DFIL1%" /C:"%_DFIL2%"
') do (
rem // Store name of currently iterated directory:
set "TDIR=%%D"
rem // Extract first (from) and second (to) numeric parts of directory names:
for /F "eol=| tokens=1-2 delims=- " %%S in ("%%D") do (
rem // Remove any leading zeros from first (from) numeric part:
set /A "FRM=0" & for /F "eol=| tokens=* delims=0" %%Z in ("%%S") do set /A "FRM=%%Z"
rem // Remove any leading zeros from second (to) numeric part:
set /A "TOO=0" & for /F "eol=| tokens=* delims=0" %%Z in ("%%T") do set /A "TOO=%%Z"
)
rem // Toggle delayed variable expansion to avoid trouble with `!`:
setlocal EnableDelayedExpansion
rem /* Do integer comparisons to check whether the numeric part of the file name
rem lies within the range given by the directory name (from/to): */
if !INT! geq !FRM! if !INT! leq !TOO! (
rem // Numeric part of file name lies within range, hence try to move file:
if defined _SUBDIR (
2> nul md "!TDIR!\!NUM!"
ECHO move "!FILE!" "!TDIR!\!NUM!\"
) else (
ECHO move "!FILE!" "!TDIR!\"
)
)
endlocal
)
rem // Return from target directory:
popd
)
)
rem // Return from source directory:
popd
)
endlocal
exit /B
You may need to adapt a few constants to your situation in the section commented with Define constants here:
at the top.
After having tested the script for the correct output, remove the upper-case ECHO
commands in front of the move
commands! In order to avoid multiple 1 file(s) moved.
messages, replace these ECHO
commands by > nul
.
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.