I suggest to use this batch file for the file moving task.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "delims=" %%I in ('dir "C:\Temp\*.jpg" /A-D /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /V /C:"\\pre\\" /C:"\\post\\"') do (
if not exist "%%~dpIpre\" md "%%~dpIpre"
move /Y "%%I" "%%~dpIpre\"
)
endlocal
FOR starts in background one more command process with %ComSpec% /c
and the specified command line appended as additional arguments. So there is executed with Windows installed into C:\Windows
in background:
C:\Windows\System32\cmd.exe /c dir "C:\Temp\*.jpg" /A-D /B /S 2>nul | %SystemRoot%\System32\findstr.exe /I /L /V /C:"\\pre\\" /C:"\\post\\"
DIR executed by the background command process searches
- in directory
C:\Temp
and all its subdirectories because of option /S
- just for files because of option
/A-D
(attribute not directory)
- matching the wildcard pattern
*.jpg
- and outputs in bare format because of option
/B
- just the file names with full path because of option
/S
.
This list of file names is redirected from STDOUT (standard output) of background command process with redirection operator |
to STDIN (standard input) of FINDSTR which searches
- for lines containing case-insensitive because of option
/I
- either the literal string
\pre\
or the literal string \post\
- and outputs the inverted result because of option
/V
, i.e. the lines not containing \pre\
or \post\
.
So FINDSTR is used here as filter to get from the list of *.jpg file names output by DIR with full path just those file names which do not have \pre\
or \post\
in their path to exclude the JPEG files which are already in one of the two subdirectories with name pre
or post
.
2>nul
after the arguments of command DIR suppresses the error message output by DIR if it cannot find any *.jpg file name in C:\Temp
and its subdirectories by redirecting the error message written to STDERR (standard error) to the device NUL.
Read the Microsoft article about Using command redirection operators for an explanation of 2>nul
. The redirection operators >
and |
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 findstr
with using a separate command process started in background.
FOR with option /F
captures everything written to handle STDOUT of started command process by FINDSTR and processes this output line by line after started cmd.exe
terminated itself. It is very important here to process a captured list of file names and do not iterate over one file name after the other returned by the file system because of the files matched by wildcard pattern *.jpg are moved during each loop iteration within the directory structure. So the directory entries matching *.jpg changes on each loop iteration and therefore it is required that a list of file names is processed loaded into memory before moving the files.
FOR with option /F
ignores empty lines which do not occur here.
FOR with option /F
would split up each line into substrings using normal space and horizontal tab as string delimiters and would assign just first space/tab delimited string to specified loop variable I
if not starting with default end of line character ;
in which case the line would be completely ignored like an empty line.
A file name with full path cannot start with ;
. So default eol=;
must not be modified here. But the line splitting behavior is counterproductive because of a full qualified file name can contain one or more spaces. For that reason the option delims=
is used to define an empty list of string delimiters which disables completely the line splitting behavior.
Therefore each full file name output by DIR not containing \pre\
or \post\
in path as filtered out by FINDSTR is assigned to loop variable I
one after the other.
It is checked next if there is for the current JPEG file a subfolder pre
and this folder is created if not already existing. Then the current JPEG file is moved into the subdirectory pre
with overwriting the file in pre
with exactly the same file name.
So this batch file can be executed multiple times on C:\Temp
as it ignores all *.jpg files in all subdirectories pre
and post
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
dir /?
echo /?
endlocal /?
findstr /?
for /?
if /?
md /?
move /?
setlocal /?