Хотите знать, успешно ли я устанавливаю переменные в командном файле? - PullRequest
0 голосов
/ 25 апреля 2019

Я запускаю командный файл в командной строке Windows, и результаты эха кажутся правильными. Но когда я обрабатываю данные дальше, результат показывает, что один из файлов не существует, однако, он хорошо отражается ранее.

Кроме того, после запуска пакета я попытался отобразить переменные, установленные в пакете ранее, все не удалось. Мне интересно, почему, успешно ли я устанавливаю переменные.

setlocal ENABLEDELAYEDEXPANSION
for /f %%f in ('dir /ad /b ') do (
    echo %%f
    pause
    pushd %%f
    for /d "tokens=1,2 delims=:" %%a in ('dir /b *.a*.dat in %%f' ) do (
        set COM_DATA=%%a
        echo !COM_DATA!
        set COM_V=%%f\com-v.dat
        echo !COM_V!
        set COM_M=%%f\com-M.dat
        echo !COM_M!
     ::some data process
    )
    chdir
    popd
)
endlocal

Я ожидаю, что смогу повторить все переменные.

Ответы [ 2 ]

1 голос
/ 25 апреля 2019

Есть много ошибок.Я рекомендую открыть окно командной строки, запустить 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.

0 голосов
/ 25 апреля 2019

Этот пример делает то же самое, что и указанный вами код, на основе предоставленной вами информации :

@Echo Off
Set "COM_DATA=%%B"
Set "COM_V=%%A\com-v.dat"
Set "COM_M=%%A\com-M.dat"
For /D %%A In (*)Do (
    Echo %%A
    For %%B In ("%%A\*.a*.dat")Do (
        Echo %COM_DATA%
        Echo %COM_V%
        Echo %COM_M%
        Rem Some data process
    )
)
Pause

Как только вы будете удовлетворены результатами выполнения кода, (перед любой модификацией) , вы можете, если хотите, удалить все строки Echo и Rem. Я не использовал команды PushD и PopD, так как не видел причин для их использования, учитывая предоставленную информацию. Я также установил переменные вне блоков For, потому что это означает, что они будут нуждаться в установке только один раз, не на каждой итерации , и это устраняет необходимость задерживать расширение.

Возможно, вам придется рассмотреть возможность изменения каждого экземпляра %%A на %%~fA, если ваш код процесса требует полных путей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...