Цикл 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.