There are lots of mistakes. I recommend opening a command prompt window, run for /?
and read the output help/documentation for command FOR. See also Microsoft's documentation for Windows Commands and even better SS64.com - A-Z index of the Windows CMD command line.
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /D %%I in (*) do (
echo Processing directory "%%~fI" ...
pushd "%%I"
for %%J in (*.a*.dat) do (
set "COM_DATA=%%J"
echo !COM_DATA!
set "COM_V=%%I\com-v.dat"
echo !COM_V!
set "COM_M=%%I\com-M.dat"
echo !COM_M!
rem some data process
)
popd
)
endlocal
Read this answer for details about the commands SETLOCAL and ENDLOCAL. The second line is required because of definition of environment variables inside a command block referenced also from within the command block. The disadvantage is that directory and file names containing one or more !
are not correct processed by this batch file because of enabled delayed expansion.
It would be better to use in second line at end DisableDelayedExpansion
instead of EnableDelayedExpansion
and do not define the environment variables COM_DATA
, COM_V
and COM_M
, but use in code not shown %%J
, %%I\com-v.dat
and %%I\com-M.dat
.
The outer FOR loop searches in current directory for any non-hidden subdirectory and runs on each found subdirectory the commands inside outer command block. The current directory can by any directory. It must not be the directory containing the batch file. Use instead of *
the string "%~dp0*"
to iterate over non-hidden subdirectories in directory of the batch file independent on what is the current directory on starting the batch file. On using just *
the directory name without path is assigned to loop variable I
. On using "%~dp0*"
the directory name with full path is assigned to loop variable I
.
pushd "%%I"
makes the current subdirectory the current directory for the command process executing the batch file.
The inner FOR loop searches in the current directory for non-hidden files matching the specified wildcard pattern and assigns to loop variable J
the file name without path.
Do not use ::
as comment. This is an invalid label. Valid and invalid labels inside a command block results in unexpected behavior on execution of the command block. There is the command REM (remark) to write a comment in a batch file. Please note that a command line with command REM is a command line like every other command line and therefore also processed and executed by cmd.exe
as described in detail at How does the Windows Command Interpreter (CMD.EXE) parse scripts?
popd
restores initial current directory before processing of batch file continues with outer FOR.
endlocal
restores initial environment which means all environment variables defined or modified after setlocal
are discarded and initial environment variables list is restored as well as initial current directory on starting the batch file and initial states of command extensions and delayed environment variable expansion.
For completes the same batch file with using command DIR twice to iterate over captured lists of directories and file names making it possible to change the list of *.a*.dat
files by code of inner FOR loop and add subdirectories to current or batch file directory by inner or outer FOR loop.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir * /AD-H /B 2^>nul') do (
echo Processing directory %%~fI ...
pushd "%%I"
for /F "eol=| delims=" %%J in ('dir *.a*.dat /A-D-H /B 2^>nul') do (
set "COM_DATA=%%J"
echo !COM_DATA!
set "COM_V=%%I\com-v.dat"
echo !COM_V!
set "COM_M=%%I\com-M.dat"
echo !COM_M!
rem some data process
)
popd
)
endlocal
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.
dir /?
echo /?
endlocal /?
for /?
popd /?
pushd /?
rem /?
set /?
setlocal /?
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 with %ComSpec% /C
.