Есть много ошибок.Я рекомендую открыть окно командной строки, запустить for /?
и прочитать справку / документацию по выводу команды FOR .См. Также документацию Microsoft для Команды Windows и даже лучше SS64.com - индекс AZ командной строки Windows CMD .
@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
Прочитайте этот ответ для получения подробной информации о командах SETLOCAL и ENDLOCAL .Вторая строка требуется из-за определения переменных среды внутри командного блока, на который ссылаются также из командного блока.Недостатком является то, что имена каталогов и файлов, содержащие один или несколько !
, некорректно обрабатываются этим пакетным файлом из-за включенного отложенного расширения .
Было бы лучше использовать во второй строкев конце DisableDelayedExpansion
вместо EnableDelayedExpansion
и не определяйте переменные среды COM_DATA
, COM_V
и COM_M
, но используйте в коде, который не показан %%J
, %%I\com-v.dat
и %%I\com-M.dat
.
Внешний цикл FOR ищет в текущем каталоге любой не скрытый подкаталог и запускает в каждом найденном подкаталоге команды внутри внешнего блока команд.Текущий каталог может быть любым каталогом.Это не должен быть каталог, содержащий пакетный файл.Вместо *
используйте строку "%~dp0*"
, чтобы выполнить итерацию по скрытым подкаталогам в каталоге пакетного файла независимо от того, какой каталог является текущим при запуске пакетного файла.При использовании только *
имя каталога без пути присваивается переменной цикла I
.При использовании "%~dp0*"
имя каталога с полным путем присваивается переменной цикла I
.
pushd "%%I"
делает текущий подкаталог текущим каталогом для командного процесса, выполняющего пакетный файл.
Внутренний цикл FOR ищет в текущем каталоге не скрытые файлы, соответствующие указанному шаблону подстановочного знака, и присваивает переменной цикла J
имя файла без пути.
Не использовать ::
как комментарий.Это недействительный ярлык.Допустимые и недействительные метки внутри командного блока приводят к неожиданному поведению при выполнении командного блока.Есть команда REM (примечание) для записи комментария в командный файл.Обратите внимание, что командная строка с командой REM является командной строкой, как и любая другая командная строка, и поэтому также обрабатывается и выполняется cmd.exe
, как подробно описано в Как работает интерпретатор команд Windows (CMD).EXE) сценарии разбора?
popd
восстанавливает исходный текущий каталог, прежде чем обработка пакетного файла продолжается с внешним FOR .
endlocal
восстанавливает исходную средуэто означает, что все переменные среды, определенные или измененные после setlocal
, отбрасываются и восстанавливается начальный список переменных среды, а также начальный текущий каталог при запуске пакетного файла и начальные состояния расширений команд и отложенное расширение переменных среды.
For завершает один и тот же пакетный файл, дважды используя команду DIR , чтобы перебрать захваченные списки каталогов и имен файлов, что позволяет изменить список файлов *.a*.dat
по коду внутреннего FOR цикл и добавить подкаталоги в текущий или бкаталог файлов atch по внутреннему или внешнему циклу FOR .
@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
Чтобы понять используемые команды и их работу, откройте окно командной строки, выполните там следующие команды и полностью прочитайтевсе страницы справки отображаются для каждой команды очень тщательно.
dir /?
echo /?
endlocal /?
for /?
popd /?
pushd /?
rem /?
set /?
setlocal /?
Прочитайте статью Microsoft о Использование операторов перенаправления команд для объяснения 2>nul
.Оператор перенаправления >
должен быть экранирован с помощью символа вставки ^
в командной строке FOR , чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , котораявыполняет встроенную командную строку dir
в отдельном командном процессе, запущенном в фоновом режиме с %ComSpec% /C
.