I think, you need a batch file like this:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=E:\customer files"
for /F "eol=| delims=" %%I in ('dir /A-D-H /B "%SourceFolder%\* *.pdf" 2^>nul') do call :MoveFile "%SourceFolder%\%%I"
endlocal
goto :EOF
:MoveFile
for /F "eol=| tokens=1 delims= " %%J in ("%~n1") do set "TargetFolder=%~dp1%%J"
for /D %%J in ("%TargetFolder%*") do move /Y %1 "%%J\" & goto :EOF
md "%TargetFolder%"
if errorlevel 1 goto :EOF
move /Y %1 "%TargetFolder%\"
goto :EOF
The first FOR executes in a separate command process started with cmd.exe /C
in background the command line
dir /A-D-H /B "E:\customer files\* *.pdf" 2>nul
The command DIR lists to STDOUT of separate command process
- the file names of all non-hidden files in specified directory
E:\customer files
because of /A-D-H
- in bare format with just file name and file extension because of
/B
- matching the wildcard pattern
* *.pdf
.
DIR outputs an error message to STDERR redirected with 2>nul
to device NUL to suppress it if no directory entry is found matching these requirements.
Read the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul
. The redirection operator >
must be escaped with caret character ^
on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir
command line with using a separate command process started in background.
FOR captures everything output to STDOUT of separate command process and process the captured text line by line.
Empty lines are ignored by FOR which do not occur here except no matching file name was found by DIR.
FOR ignores by default on using /F
all lines starting with a semicolon. A file name can start with ;
and therefore eol=|
is used to redefine the end of line character to a vertical bar which a file name cannot contain.
FOR splits up a line by default into substrings (tokens) using space/tab as delimiters and assigns just first space/tab delimited string to specified loop variable I
. This line splitting behavior is disabled by delims=
which defines an empty list of delimiters.
So the entire file name is assigned to loop variable I
which is concatenated with source folder path to a full qualified file name and passed to subroutine MoveFile
.
The first FOR in subroutine MoveFile
processes the file name string without path and file extension referenced with %~n1
and splits it up on spaces. The first space delimited string is assigned to specified loop variable J
which is concatenated with drive and path of source file referenced with %~dp1
ending always with a backslash to an environment variable TargetFolder
.
The second FOR in subroutine MoveFile
searches for a non-hidden directory starting with the first space separated string of current file name, i.e. starting with the number at beginning of the PDF file names. If a directory matching this simple wildcard pattern is found in the source folder, its full qualified name is assigned to loop variable J
and command MOVE is executed to move the PDF file into this folder. Then the FOR loop and the subroutine MoveFile
is exited and batch file execution continues on first FOR command line at top of the file.
Otherwise there is no subdirectory in source directory for the current file. So the batch file creates this directory. If that fails for some reasons, the subroutine is exited without moving the current file. Otherwise the file is moved into just created directory.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
move /?
set /?
setlocal /?
See also Single line with multiple commands using Windows batch file for an explanation of operator &
and Where does GOTO :EOF return to?