Цикл bat файл: Как организовать цикл в bat или cmd файле
Содержание
windows — Как использовать переменную цикла в .bat файла в цикле for?
Вопрос задан
Изменён
8 месяцев назад
Просмотрен
602 раза
Имеется следующий код в .bat файле:
@echo off set NAMEFILE=version rem counting commas set "f=%VERSION%" set "vz=," set /a "z=0,n=0" for /f "delims=" %%a in ('findstr /r /c:"\%vz%" "%f%"') do set "s=%%a"& call :# <+ (for /f "tokens=1,2 delims==" %%b in ('more') do set /a "z+=%%b")& del+ set /a z =%z% + 1 rem цикл с проблемой rem tokens=%%a* - часть кода, содержащая проблему for /l %%a in (1,1,%z%) do for /f "tokens=%%a* delims=," %%i in (%NAMEFILE%) do @echo %%i>File_%%a.vers :# setlocal enabledelayedexpansion 2>nul for %%a in ("!s:~%n%,1!") do ( if "%%~a"=="%vz%" set /a z+=1 if not "%%~a"=="" set /a n+=1& goto # ) endlocal exit /b
Я не знаю, что делать с tokens=%%a
. Переменная %%a
не видна во время выполнения (как я полагаю). Может быть проблема в символе %
? Думаю, что он должен быть экранирован. Помогите, если знаете ответ.
- windows
- bat
6
Нельзя использовать ни delayed expansion (не знаю аналог термина на русском), ни for-parameter expansion в части параметров команды FOR (то же самое верно и для if). Это вызвано тем, как их обрабатывает пакетный парсер.
Но процентное расширение всё ещё работает. В моём пример нельзя использовать его встроенным (inline), поэтому приходится использовать вспомогательную функцию.
... for /l %%a in (1,1,%z%) do call :helper_func %%a ... :helper_func for /f "tokens=%1* delims=," %%i in (%NAMEFILE%) do @echo %%i>File_%%a.vers
Выглядит странно, что в helper_func
всё ещё можно использовать %%a
в echo %%i>File_%%a
. Это эффект того, что все используемые в данный момент параметры for
видны во всех циклах for
.
идея пользователя jeb
Тоже искал решение и нашел, оказалось всё просто:
Setlocal EnableDelayedExpansion CHCP 1251 CLS REM Организация цикла SET BASES1C=(base1 base2 base3 base4) FOR %%i IN %BASES1C% DO ( SET PGDATABASE=%%i echo !PGDATABASE! )
Зарегистрируйтесь или войдите
Регистрация через Google
Регистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки
Цикл с условием bat file
Задать вопрос
Вопрос задан
Изменён
5 лет 4 месяца назад
Просмотрен
686 раз
Первое условие срабатывает, а остальные не срабатывают. Хотя по логике все должно работать.
Батник вызывается с параметрами: my.bat -d 123 -dh 333
:while if "%1"=="-d" ( set WORKDIR=%2 & shift & shift & goto :while ) if "%1"=="--work-dir" ( set WORKDIR="%2" & shift & shift & goto :while ) if "%1"=="-l"( set LOGDIR="%2" & shift & shift & goto :while) if "%1"=="-log-dir"( set LOGDIR="%2" & shift & shift & goto :while) if "%1"=="-dh"( set DBHOST="%2" & shift & shift & goto :while) if "%1"=="--host"( set DBHOST=%2 & shift & shift & goto :while) if "%1"=="-db"( set DATABASE=%2 & shift & shift & goto :while) if "%1"=="--database"( set DATABASE=%2 & shift & shift & goto :while) if "%1"=="-u"( set DBUSER=%2 & shift & shift & goto :while) if "%1"=="--db-user"( set DBUSER=%2 & shift & shift & goto :while) if "%1"=="-p"( set DBPASSWORD=%2 & shift & shift & goto :while) if "%1"=="--db-password"( set DBPASSWORD=%2 & shift & shift & goto :while) if "%1"=="-j"( set JOBS=%2 & shift & shift & goto :while) if "%1"=="--jobs"( set JOBS=%2 & shift & shift & goto :while) if "%1"=="-ld"( set LOGDROP=%2 & shift & shift & goto :while) if "%1"=="--log-drop"( set LOGDROP=%2 & shift & shift & goto :while) if "%1"=="-pt"( set PROJECTSTYPE=%2 & shift & shift & goto :while) if "%1"=="--projects-type"( set PROJECTSTYPE=%2 & shift & shift & goto :while) if "%1"=="-pn"( set PROJECTNAME=%2 & shift & shift & goto :while) if "%1"=="--projects-name"( set PROJECTNAME=%2 & shift & shift & goto :while) if "%1"=="-jc"( set JOBSBATCH=%2 & shift & shift & goto :while) if "%1"=="--jobs-batch"( set JOBSBATCH=%2 & shift & shift & goto :while) if "%1"=="-def"( set DEFAULT=YES & shift & goto :while) if "%1"=="-default"( set DEFAULT=YES & shift & goto :while) if "%1"==""(set /a POSITIONAL+=%1 & shift & goto :endwhile) :endwhile
Полный код скрипта:
wmic csproduct get "UUID">mac. txt echo %UUID% SET /P UUID=<mac.txt set file = mac.txt set old = "UUID" more +1 "mac.txt" >"file.txt.new" move /y "file.txt.new" "mac.txt" >nul SET /P UUID=<mac.txt rem For /F "usebackq tokens=* skip=1 delims=" %%i In (%file%) Do Set UUID=%%i echo %UUID% pause :uniqLoop set "WORKDIR=\bat~%RANDOM%.tmp" if exist "%WORKDIR%" goto :uniqLoop echo >"%WORKDIR%" :: Запись переменной в файл для проверки echo %perem% set LOGDIR="./Logs" set LOGDROP=NO set DBHOST=localhost set DATABASE=DAE set DBUSER=root set DBPASSWORD=1 set JOBS=0.8 set PROJECTSTYPE=* set PROJECTNAME=* set JOBSRECHECK=5 set JOBSBATCH=100 set DEFAULT=NO for %%a in (%CD%) do set /a cnt+=1 REM echo %cnt% rem ## worker_start.sh -d tmp - l set f_sr="-d" set POSITIONAL=() :while pause echo %1 echo %2 pause if "%1"=="-d" ( set WORKDIR=%2 & shift & shift & goto :while ) if "%1"=="--work-dir" ( set WORKDIR="%2" & shift & shift & goto :while ) if "%1"=="-l"( set LOGDIR="%2" & shift & shift & goto :while) if "%1"=="-log-dir"( set LOGDIR="%2" & shift & shift & goto :while) if "%1"=="-dh"( set DBHOST="%2" & shift & shift & goto :while) if "%1"=="--host"( set DBHOST=%2 & shift & shift & goto :while) if "%1"=="-db"( set DATABASE=%2 & shift & shift & goto :while) if "%1"=="--database"( set DATABASE=%2 & shift & shift & goto :while) if "%1"=="-u"( set DBUSER=%2 & shift & shift & goto :while) if "%1"=="--db-user"( set DBUSER=%2 & shift & shift & goto :while) if "%1"=="-p"( set DBPASSWORD=%2 & shift & shift & goto :while) if "%1"=="--db-password"( set DBPASSWORD=%2 & shift & shift & goto :while) if "%1"=="-j"( set JOBS=%2 & shift & shift & goto :while) if "%1"=="--jobs"( set JOBS=%2 & shift & shift & goto :while) if "%1"=="-ld"( set LOGDROP=%2 & shift & shift & goto :while) if "%1"=="--log-drop"( set LOGDROP=%2 & shift & shift & goto :while) if "%1"=="-pt"( set PROJECTSTYPE=%2 & shift & shift & goto :while) if "%1"=="--projects-type"( set PROJECTSTYPE=%2 & shift & shift & goto :while) if "%1"=="-pn"( set PROJECTNAME=%2 & shift & shift & goto :while) if "%1"=="--projects-name"( set PROJECTNAME=%2 & shift & shift & goto :while) if "%1"=="-jc"( set JOBSBATCH=%2 & shift & shift & goto :while) if "%1"=="--jobs-batch"( set JOBSBATCH=%2 & shift & shift & goto :while) if "%1"=="-def"( set DEFAULT=YES & shift & goto :while) if "%1"=="-default"( set DEFAULT=YES & shift & goto :while) if "%1"==""(set /a POSITIONAL+=%1 & shift & goto :endwhile) :endwhile echo "Hello, while is over" echo "Worker start with options:" echo %UUID% echo %WORKDIR% echo %LOGDIR% echo %LOGDROP% echo %DBHOST% echo %DATABASE% echo %DBUSER% echo %DBPASSWORD% echo %JOBS% echo %PROJECTSTYPE% echo %PROJECTNAME% echo %JOBSRECHECK% echo %JOBSBATCH% echo %DEFAULT% echo %POSITIONAL% python worker_start. py --work-dir %WORKDIR% --log-dir %LOGDIR% -dh %DBHOST% -db %DATABASE% -u %DBUSER% -p %DBPASSWORD% -j %JOBS% -ld %LOGDROP% -pt %PROJECTSTYPE% -pn %PROJECTNAME% -jc %JOBSRECHECK% -jb %JOBSBATCH% -def %DEFAULT% --UUID %UUID% pause
Проблема в пробелах.
Вот так:
if "%1"=="-dh" ( set DBHOST="%2" & shift & shift & goto :while )
(обратите внимание на пробел перед скобкой) у меня -dh
детектируется.
Зарегистрируйтесь или войдите
Регистрация через Google
Регистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки
For — Циклические команды — Windows CMD
For — Циклические команды — Windows CMD — SS64. com
- SS64
- CMD
- Практическое руководство
Условно выполнить команду несколько раз.
синтаксис-ДЛЯ-файлов FOR %%parameter IN ( набор ) DO команда синтаксис-FOR-Files-Rooted at Path FOR /R [[диск:]путь] %%параметр IN ( набор ) DO команда синтаксис-FOR-папки FOR /D %%параметр IN ( набор_папок ) DO команда синтаксис-FOR-Список чисел FOR /L %%параметр IN (начало,шаг,конец) DO команда синтаксис-FOR-содержимое файла FOR /F ["опции"] %%параметр IN (набор имен файлов) DO команда FOR /F ["опции"] %%параметр IN ("Текстовая строка для обработки") DO команда синтаксис-FOR-Command Результаты FOR /F ["параметры"] %%параметр IN ("команда для обработки") DO команда
Действие команды FOR можно резюмировать как. ..
- Взять набор данных
- Сделать параметр FOR %%G равным некоторой части этих данных
- Выполнить команду (необязательно используя параметр как часть команды).
- Повторить для каждого элемента данных
Если вы используете команду FOR в командной строке, а не в пакетной программе, используйте только один знак процента: %G вместо %%G .
ДЛЯ Параметры
Первый параметр должен быть определен с использованием одного символа, например, буквы G.
FOR %%G IN …
На каждой итерации цикла FOR вычисляется предложение IN ( ….) и %%G устанавливается на другое значение
Если в результате этого пункта получается одно значение, то %%G устанавливается равным этому значению и выполняется команда.
Если предложение приводит к нескольким значениям, то для хранения каждого из них неявно определяются дополнительные параметры. Они автоматически назначаются в алфавитном порядке %%H %%I %%J . .. (неявное определение параметра)
Если параметр ссылается на файл, то можно использовать расширенную ссылку на переменную для извлечения имени файла/пути/даты/размера.
Конечно, вы можете выбрать любую букву алфавита, кроме %%G.
%%G — хороший выбор, поскольку он не конфликтует ни с одной из букв формата имени пути (a, d, f, n, p, s, t, x) и обеспечивает самый длинный ряд неконфликтующих букв для использования как неявные параметры.
G > H > I > J > K > L > M
Буквы формата чувствительны к регистру, поэтому использование заглавной буквы также является хорошим способом избежать конфликтов %%A, а не %%a.Если вам нужно много букв параметров, полный список от младших до старших:
> ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ˆ _ ` a b c d e ж g h i j k l m n o p q r s t u v w x y z { | }Начиная с %A, вы можете использовать 29 символов, прежде чем вам придется экранировать любые знаки препинания. [источник]
Использование переменных в цикле FOR
Переменные расширяются в начале цикла FOR и не обновляются до тех пор, пока не будет завершена вся секция DO.
В следующем примере подсчитываются файлы в текущей папке, но %count% всегда возвращает 1:.
@эхо от
НАБОР=1
FOR /f «tokens=*» %%G IN (‘dir /b’) DO (
эхо %count%:%%G
установить /количество+=1 )Чтобы обновить переменные в каждой итерации цикла, мы должны либо использовать EnableDelayedExpansion, либо использовать механизм CALL :subroutine, как показано ниже:
@эхо от
НАБОР=1
FOR /f «tokens=*» %%G IN (‘dir /b’) DO (вызов : подпрограмма «%%G» )
GOTO: eof: подпрограмма
эхо %count%:%1
установить /количество+=1
ПЕРЕЙТИ: eof
Вложенные команды FOR
Команды FOR могут быть вложенными FOR %%G… DO (для %%U… do …)
при размещении команд выберите разные буквы для каждой части. тогда ты сможешь
обратитесь к обоим параметрам в окончательной команде DO.Пример выхода из внутреннего цикла двух вложенных циклов FOR см. на странице ВЫХОД.
Уровни ошибок
FOR сама по себе не устанавливает и не сбрасывает уровень ошибки, оставляя это на усмотрение команды звонят.
Единственным исключением является использование подстановочного знака, если подстановочный знак не соответствует ни одному файлу, то FOR вернет %ERRORLEVEL% = 5.
FOR — это внутренняя команда.
Если расширения команд отключены, команда FOR будет
поддерживают только базовый синтаксис без расширенных переменных:
FOR %%parameter IN (set) DO команда [параметры команды]
Примеры
FOR /F «tokens=1-5» %%A IN («Это короткое предложение») DO @echo %%A %%B %%D
приведет к выводу: Это короткое
Создайте набор из 26 папок, по одной на каждую букву алфавита:
ДЛЯ %%G IN (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v ,w,x,y,z) DO (md C:\demo\%%G)
«Тот, кто не помнит прошлого, обречен на его повторение» — Джордж Сантаяна
Связанные команды
FOR — Зациклить набор файлов в одной папке.
FOR /R — Циклический просмотр файлов (рекурсивные подпапки) .
FOR /D — Перебрать несколько папок.
FOR /L — Перебрать диапазон чисел.
FOR /F — циклический просмотр элементов в текстовом файле.
FOR /F — циклический просмотр вывода команды.
Параметры/аргументы %~ опции.
FORFILES — Пакетная обработка нескольких файлов.
GOTO — указание пакетной программе перейти к помеченной строке.
IF-Условное выполнение команды.
Эквивалент PowerShell: ForEach-Object — цикл для каждого объекта в конвейере.
Эквивалентная команда bash (Linux): awk или for var в [списке]; сделать — развернуть перечислить и выполнить команд .
Copyright © 1999-2023 SS64.com
Некоторые права защищены
Для — Циклический просмотр файлов — Windows CMD
Для — Циклический просмотр файлов — Windows CMD — SS64.com
- SS64
- CMD
- Практическое руководство
Условно выполнить команду над несколькими файлами.
Синтаксис ДЛЯ %%параметра IN ( набор ) DO команда Ключ set : Набор из одного или нескольких файлов, разделенных любым стандартным разделителем. в круглых скобках (файл1,файл2). Можно использовать подстановочные знаки. команда : Команда для выполнения, включая любые параметры. Это может быть одна команда или если вы приложите ее in (скобки), несколько команд, по одной на строку. %%parameter : заменяемый параметр: например в пакетном файле используйте %%G (в командной строке %G)
Команда FOR в основном используется для обработки файлов, но вы также можете обрабатывать текстовую строку:
FOR %%G IN («Hello World») DO Echo %%G
Это не совсем полезно, так как это почти то же самое, что и Echo Hello World
. Хотя можно использовать подстановочные знаки, альтернативным методом обработки файлов является
чтобы FOR /F обрабатывал выходные данные команды ‘DIR /b’ Это может быть полезно, когда вы хотите использовать DIR
опции, такие как сортировка.
Параметры FOR (%%A – %%Z)
Прочтите главную страницу введения FOR для получения полного описания назначения заменяемого параметра %%.
Уровни ошибок
FOR сама по себе не устанавливает и не сбрасывает уровень ошибки, оставляя это на усмотрение вызываемой команды .
Единственным исключением является использование подстановочного знака, если подстановочный знак не соответствует ни одному файлу, то FOR вернет %ERRORLEVEL% = 5.
FOR — это внутренняя команда.
Примеры
Если вы используете команду FOR в командной строке, а не в пакетной программе, используйте только один знак процента: (%G вместо %%G ).
Эхо дней недели:
FOR %%G IN (понедельник, вторник, среда, четверг, пятница) DO Echo %%G
Повторить дни недели, составив из них предложение:
ДЛЯ %%G IN (понедельник, вторник, среда, четверг, пятница) DO Echo Каждый %%G — рабочий день!
Копировать один файл:
ДЛЯ %%G IN (MyFile.