Бат-файлы ведут свою историю со времен MS-DOS. Новые фичи добавлялись с сохранением обратной совместимости. Из-за этого многое в языке bat-файлов, как мы увидим далее, нелогично и неудобно.
Вместе с тем, в bat-файле можно использовать переменные, условия, циклы и подпрограммы. При помощи некоторых костылей можно передавать данные на вход команд и разбирать их вывод. Проще говоря, можно программировать.
В этой статье мы постараемся дать обзор основных элементов языка командного интерпретатора Windows, с помощью которых можно реализовать любой алгоритм.
Зачем же сегодня использовать этот язык? Главным образом, для автоматизации выполнения консольных команд. Запуск команд выполняется в bat-файле проще, чем в каком-либо другом языке: инструкция запуска команды – это сама команда без каких бы то ни было ключевых слов, знаков препинания и подключаемых библиотек.
Для сравнения, Java, .NET и Python для выполнения этой простой задачи требуют подключить библиотеку/сборку/модуль и вызвать метод.
Язык C++ сам по себе вообще не определяет для этого стандартный и независимый от платформы способ. Тут вам понадобится библиотека целевой операционной системы. В Windows это windows.h и функция CreateProcess(), а в Linux надо вызвать fork(), а затем exec().
Второе место по простоте вызова команд операционной системы занимает Perl – в нем достаточно заключить команду в обратные кавычки (``).
Первое место с bat-файлами делят PowerShell и bash.
Зачем же разбирать командный интерпретатор, а не Power Shell, который, кроме всего прочего, дает доступ ко всему богатству возможностей .NET Framework?
Прежде всего, ради искусства. Разные люди делают интересные вещи чисто на bat-файлах именно потому, что это сложно. Т.е. можно рассматривать язык командного интерпретатора как эзотерический язык программирования.
Кроме того, как-то раз в реальном проекте мне пришлось поддерживать bat-скрипты. Так что рано их списывать со счетов как морально устаревшую технологию.
Еще одно полезное отличительное свойство командного интерпретатора – для получения справки не нужен ни Гугл, ни интернет. Нужно лишь набрать команду help. Причем, информация русском языке, если у вас русская винда.
Переменные
Переменные в bat-файлах – это переменные окружения. Это значит, что все переменные, установленные скриптом, доступны процессам, которые он запускает. Это надо иметь ввиду при работе с паролями.
Переменные создаются и изменяются командой set:
set hello=world
Создали переменную с именем hello и значением world.
Команда set без параметров выводит список всех переменных.
Следующая строка выведет слово «world»:
echo %hello%
Имена переменных нечувствительны к регистру. Следующая строка тоже выведет слово «world»:
echo %HELLO%
Значения переменных могут содержать знак равенства:
set equation=x=y
echo %equation%
выведет x=y
Значение переменных вставляются в текст команды, и только потом происходит ее разбор. Это значит, что переменная может содержать саму команду и/или любое количество параметров.
Специальные переменные
Переменные, перечисленные ниже, используют один знак %, только в начале, в отличие от обычных переменных.
%0 – имя bat-файла, который сейчас выполняется, в том виде, как оно указано в командной строке. Для запуска bat-файла его имя может быть написано с полным путем, с относительным путем, без пути, с расширением, без расширения, маленькими или заглавными буквами. Соответственно, в переменной %0 оно может оказаться во всех этих вариантах. Но в любом случае командой %0 скрипт запускает сам себя.
%1, %2 … %9 – параметры. Командная строка разделяется на токены по пробелам. При этом каждая часть, заключенная в кавычки, считается одним токеном. Кавычки, если есть, тоже попадают в эти переменные.
%* – все параметры, т.е. всё, что идет в командной строке после имени bat-файла, со всеми кавычками и пробелами, какие есть.
%errorlevel% — код возврата последней команды
%CD% — текущая директория
%DATE% и %TIME% — текущие дата и время
%RANDOM% — случайное число
Преобразование параметров при подстановке
%~1 – первый параметр без кавычек. Как вы помните, параметр может быть указан либо в кавычках, либо без них, и кавычки, если они есть, будут и в переменной. От того, есть ли кавычки в переменной, зависит, будет ли содержащее ее выражение синтаксически правильным. Проверить наличие кавычек с помощью оператора if не получится, потому что в одном из двух случаев выполнение скрипта прервется из-за синтаксической ошибки. Однако, тильда перед именем переменной гарантирует, что кавычек на месте этой переменной не будет.
%~dp0 – полный путь к папке текущего bat-файла, без имени самого файла.
%~nx0 – имя и расширение текущего bat-файла, без пути
Поставив вместо нуля другую цифру, можно аналогичным образом разобрать путь, переданный скрипту через командную строку. Это также работает с переменными циклов, но не с переменными окружения.
Цикл FOR
Это единственный вид цикла. Если нужно что-то типа while или until, то придется использовать операторы if и goto.
Зато цикл FOR имеет несколько опций, выходящих за рамки того, что обычно делает цикл
Итерирование по словам
Пример
@echo off
FOR %%a in (one two three) do echo %%a
Выводит каждое слово в новой строке:
one
two
three
@echo off отключает вывод команд. @ перед командой отключает вывод данной команды
Этот пример необходимо записать в bat-файл и запустить файл. Если вводить цикл в командной строке, то он должен выглядеть слегка иначе:
FOR %a in (one two three) do @echo %a
Да, синтаксис переменной цикла зависит от того, вводим ли мы этот цикл в командной строке или он записан в файл. Если какой-то софт запускает команду, которую вы ему укажете, и вы хотите использовать в ней цикл, синтаксис зависит от того, каким образом этот софт передает команду командному интерпретатору. Это можно делать через командную строку или через стандартный ввод. В этих случаях используется один знак процента. Вариант с файлом мы уже пробовали в примере. Там используются два знака процента.
Цикл разбирает строку в скобках по тем же правилам, что параметры командной строки: строка в кавычках – это один параметр. Пример:
@echo off
FOR %%a in ("twenty one" "twenty two") do echo %%~a
Выводит две строки:
twenty one
twenty two
Строки выводятся без кавычек, потому что использована переменная %%~a. %%a содержит кавычки.
Цикл по файлам или папкам
Следующая команда выводит список файлов в текущем каталоге:
FOR %%a in (*.*) do echo %%a
А так можно получить список папок:
FOR /D %%a in (*.*) do echo %%a
Параметр /R включает обход всех подкаталогов. При этом в переменной цикла полные пути:
FOR /R %%a in (*.*) do echo %%a
FOR /D /R %%a in (*.*) do echo %%a
Вместо «*.*» можно писать просто «*«. Результат абсолютно такой же: в обоих случаях выбираются файлы как с расширениями, так и без.
Цикл по числам с заданным шагом
Используем параметр /L, а в скобках указываем начало, шаг и конец (включительно) через запятую. Обратите внимание, что для числа, указанного как конец интервала, команда тоже будет вызвана, если длина интервала делится на шаг. Шаг может быть отрицательным.
FOR /L %%a in (10,-1,5) do @echo %%a
Выводит:
10
9
8
7
6
5
Разбор файлов и строк
FOR /F %%a in (список.txt список2.txt) do echo %%a
Каждый файл открывается, каждая строка читается и разбивается на одну или более подстрок. Подстроки записываются в отдельные переменные. Например, если переменная цикла — %%a, то будут созданы переменные %%a, %%b, %%c и т.д.
При разборе строки разделителями по умолчанию считаются пробелы и табуляции.
Вот так можно разобрать строку, указанную непосредственно:
FOR /F %%a in (“строка”) do echo %%a
А так разбирается вывод команды. Это вообще единственный способ получить вывод команды в переменную. То есть, даже если вывод состоит из одной строки, и ее не надо разбирать, всё равно приходится писать цикл.
FOR /F %%a (‘dir /B’) do echo %%a
Выводит список файлов, разбирая вывод команды dir.
Наберите help for, чтобы узнать все опции.
Вызов подпрограмм и других скриптов
Очередная контринтуитивная фича bat-файлов в том, что, если из одного bat-файла вызвать другой, выполнение первого файла не продолжится, если только не использовать ключевое слово call. То есть, мы должны разбираться, чем является команда, которую мы хотим вызвать. Если это bat-файл, то надо перед его именем написать call. Если это exe-файл или встроенная команда, то это слово не нужно. Кроме того, если вызываемый скрипт использует команду exit, то выполнение также не вернется к нам. Чтобы завершить только текущий скрипт, надо писать exit /B.
При вызове одного скрипта из другого не создается новый процесс. Поэтому переменные окружения, установленные вызванным скриптом, видны вызывающему.
В следующем примере a.bat вызывает b.bat. Этот пример также демонстрирует работу с кодом завершения процесса.
a.bat
@echo off
echo Before call
call b.bat
echo b.bat returned %errorlevel%
b.bat
echo Inside b.bat
exit /B 1
Выводит:
Before call
Inside b.bat
b.bat returned 1
Командой call также можно вызвать код, находящийся в том же файле:
@echo off
echo Before call
call :b
echo b returned %errorlevel%
goto :eof
:b
echo Inside b.bat
exit /B 1
Работает аналогично предыдущему примеру, но это один файл.
С двоеточия начинаются метки. На них можно переходить командами call и goto. В языке bat-файлов нет понятия подпрограммы. Мы будем так называть код, который вызывается через call и возвращает управление через exit /B или goto :eof. Метка :eof не определена, и это не ошибка. Эта метка не нуждается в определении. Она всегда означает конец файла. Т.е. переход на :eof – это выход – то же, что и exit /B, но без кода завершения.
Условия
if a==a echo 1
Выводит 1.
if a==b echo 1
Ничего не выводит.
Если строки до и после знаков равенства совпадают с учетом регистра, то команда выполняется, иначе не выполняется. В обеих строках можно использовать переменные. При этом надо иметь ввиду, что в переменных может быть всё, что угодно, включая знаки равенства и пустые строки. От значений переменных будет зависеть синтаксическая правильность команды.
Вот такой способ проверить параметр командной строки работает и при отсутствии параметра, и если в нем спецсимволы:
if "%~1"=="help" echo This is a test script && exit /B
Оператор && — это один из способов выполнить несколько команд под условием. На самом деле это ленивое «и», т.е. если первая команда вернет ненулевой errorlevel, то вторая уже не выполнится.
Другой способ – скобки:
if "%~1"=="help" (
echo This is help
exit /B
) else (
Echo This is the main part
)
Как видите, со скобками можно использовать слово else.
Насчет скобок нужно помнить одну вещь. Условие или цикл с блоком команд в скобках – это одна команда. Значения переменных в ней подставляются один раз в самом начале.
То есть, нельзя внутри такого блока присвоить значение переменной и позже в том же блоке его использовать. Нельзя присвоить значение на одной итерации цикла и использовать на другой.
При таких сценариях приходится выносить код в подпрограммы.
Есть еще поздняя подстановка переменных. Ее надо включать командой SETLOCAL ENABLEDELAYEDEXPANSION, а вместо символа «%» использовать «!«.
Разыменование переменных
Отсутствие в языке массивов и словарей приходится обходить, используя переменные, имена которых содержат индексы и ключи.
Допустим, переменная A содержит ключ:
set A=aaa
Записать значение по ключу можно так:
set %A%=bbb
Следующая команда выведет «bbb»:
echo %aaa%
А вот читать по ключу не так просто. Подстановка переменных не рекурсивна. То есть, нельзя, используя только знак «%», подставить «aaa» вместо «A», а затем, «bbb» вместо «aaa».
Тут нам поможет поздняя подстановка. Она тоже не рекурсивна. Однако, используя сразу оба вида подстановок, можно выполнить замену в два этапа:
SETLOCAL ENABLEDELAYEDEXPANSION
echo !%A%!
Выводит «bbb».
Желающие усложнить себе задачу отказом от поздней подстановки, могут разбирать вывод команды set при помощи цикла for:
for /F "tokens=1,2 delims==" %%a in ('set %A%') do if "%%a"=="%A%" echo %%b
Обратите внимание, что в цикле надо проверять имя переменной, которую нам вернули, даже если указать имя нужной переменной в команде set. Дело в том, что могут существовать переменные с именами, начинающимися с нужного. Если убрать параметр команды set, результат не изменится. Но указывая этот параметр, мы оптимизируем алгоритм. Но это не точно.
Арифметика
Команда set /A вычисляет выражения
SET /A A=2+3
ECHO %A%
Выводит 5
Замена подстрок
SET A=abcdefgh
ECHO %A:c=C%
Заменяет строчную букву C на заглавную. Выводит:
abCdefgh
Выбор подстроки:
ECHO %A:~4,2%
Выводит 2 символа, начиная с 5-го, в данном случае «ef«.
Ввод пользователя
SET /P A=Enter something:
Выведет приглашение для ввода и будет ждать ввода строки. Введенная строка окажется в переменной A.
Заключение
Язык командного интерпретатора имеет многолетнюю историю и дожил до наших дней. Он доступен на чистой винде и удобен для автоматизации выполнения команд. При этом он является языком программирования, и позволяет реализовать алгоритмы любой сложности. Самое главное в таком деле – найти подходящие инструменты командной строки, дающие доступ к нужным возможностям. Вместе с тем решение задач на bat-файлах с использованием ограниченного набора внешних команд может быть интересным упражнением.
декларация
Чтобы создать простую переменную и присвоить ее значению или строке, используйте команду SET :
SET var=10
Здесь код объявляет новую переменную var со значением 10 . По умолчанию все переменные хранятся внутри строки в виде строк; это означает, что значение 10 не отличается от foo1234 или Hello, World!
Заметки о кавычках
Используемые котировочные знаки будут включены в значение переменной:
SET var="new value" <-- %var% == '"new value"'
Пространства в переменных
Пакетный язык рассматривает пространства как приемлемые части имен переменных. Например, set var = 10 приведет к переменной var которая содержит значение 10 (обратите внимание на дополнительное пространство справа от var и слева от 10).
Использование кавычек для устранения пробелов
Чтобы предотвратить пробелы, используйте кавычки вокруг всего задания; имя переменной и значение. Это также предотвращает случайные конечные пробелы в конце строки (символ ␣ обозначает пробел):
SET␣var=my␣new␣value␣ <-- '%var%' == 'my new value '
SET␣"var=my␣new␣value"␣ <-- '%var%' == 'my new value'
Кроме того, используйте кавычки при объединении нескольких операторов с помощью & или | — альтернативно, поместите символ непосредственно после окончания значения переменной:
SET var=val & goto :next <-- '%var%' == 'val '
SET "var=val" & goto :next <-- '%var%' == 'val'
SET var=val& goto :next <-- '%var%' == 'val'
использование
echo %var%
Этот код будет повторять значение var
Если используется setLocal EnableDelayedExpansion , следующее будет setLocal EnableDelayedExpansion значение var (стандартное выражение% var% не будет работать в этом контексте).
echo !var!
В пакетных файлах переменные могут использоваться в любом контексте, в том числе в составе команд или частей других переменных. Вы не можете вызывать переменную до ее определения.
Использование переменных в качестве команд:
set var=echo
%var% This will be echoed
Использование переменных в других переменных:
set var=part1
set %var%part2=Hello
echo %part1part2%
Переменная замена
В отличие от других языков программирования, в пакетном файле переменная заменяется ее фактическим значением до запуска командного скрипта. Другими словами, замена выполняется, когда скрипт считывается в память командным процессором, а не при последующем запуске сценария.
Это позволяет использовать переменные как команды внутри скрипта и как часть других имен переменных в скрипте и т. Д. «Сценарий» в этом контексте является строкой или блоком кода, окруженным круглыми скобками: () .
Но это поведение означает, что вы не можете изменить значение переменной внутри блока!
SET VAR=Hello
FOR /L %%a in (1,1,2) do (
ECHO %VAR%
SET VAR=Goodbye
)
распечатает
Hello
Hello
поскольку (как вы видите, при просмотре сценария, запускаемого в окне команд), он вычисляется так:
SET VAR=Hello
FOR /L %%a in (1,1,2) do (
echo Hello
SET VAR=Goodbye
)
В приведенном выше примере команда ECHO оценивается как Hello когда скрипт считывается в память, поэтому скрипт будет эхом Hello навсегда, однако многие проходы выполняются через скрипт.
Способ достижения более «традиционного» поведения переменной (переменной, которая расширяется во время работы скрипта) заключается в том, чтобы включить «замедленное расширение». Это включает в себя добавление этой команды в скрипт перед инструкцией цикла (обычно цикл FOR, в пакетном скрипте) и использование восклицательного знака (!) Вместо знака процента (%) в имени переменной:
setlocal enabledelayedexpansion
SET VAR=Hello
FOR /L %%a in (1,1,2) do (
echo !VAR!
SET VAR=Goodbye
)
endlocal
распечатает
Hello
Goodbye
Синтаксис %%a in (1,1,2) заставляет цикл работать 2 раза: в первом случае переменная несет свое начальное значение «Hello», но на втором проходе через цикл — выполнив второй SET как последнее действие на 1-м проходе — это изменилось на измененное значение «До свидания».
Расширенная подстановка переменных
Теперь, передовая техника. Использование команды CALL позволяет процессору команд партии расширять переменную, расположенную в той же строке сценария. Это может обеспечить многоуровневое расширение путем повторного использования CALL и модификатора.
Это полезно, например, для цикла FOR. Как и в следующем примере, где у нас есть нумерованный список переменных:
"c:\MyFiles\test1.txt" "c:\MyFiles\test2.txt" "c:\MyFiles\test3.txt"
Мы можем достичь этого, используя следующий цикл FOR:
setlocal enabledelayedexpansion
for %%x in (%*) do (
set /a "i+=1"
call set path!i!=%%~!i!
call echo %%path!i!%%
)
endlocal
Выход:
c:\MyFiles\test1.txt
c:\MyFiles\test2.txt
c:\MyFiles\test3.txt
Обратите внимание, что переменная !i! сначала расширяется до его начального значения, 1, то результирующая переменная% 1 расширяется до ее фактического значения c:\MyFiles\test1.txt . Это двойное расширение переменной i . На следующей строке i снова удваивается, используя команду CALL ECHO вместе с префиксом переменной %% , затем печатается на экране (т.е. отображается на экране).
На каждом последующем проходе через цикл начальное число увеличивается на 1 (из-за кода i+=1 ). Таким образом, он увеличивается до 2 на 2 -м проходе через петлю и до 3 на 3 -м проходе. Таким образом, строка, отобранная на экран, изменяется с каждым проходом.
Объявить несколько переменных
Когда в начале партии задано несколько переменных, можно использовать короткую форму определения, используя заменяющую строку.
@echo off
set "vars=_A=good,_B=,_E=bad,_F=,_G=ugly,_C=,_H=,_I=,_J=,_K=,_L=,_D=6
set "%vars:,=" & set "%"
for /f %%l in ('set _') do echo %%l
exit /b
_A=good
_D=6
_E=bad
_G=ugly
Обратите внимание, что в приведенном выше примере переменные упорядочиваются в алфавитном порядке при печати на экран.
Использование переменной как массива
Можно создать набор переменных, которые могут действовать подобно массиву (хотя они не являются фактическим объектом массива), используя пробелы в инструкции SET :
@echo off
SET var=A "foo bar" 123
for %%a in (%var%) do (
echo %%a
)
echo Get the variable directly: %var%
Результат:
A
"foo bar"
123
Get the variable directly: A "foo bar" 123
Также можно объявить переменную с помощью индексов, чтобы вы могли получить определенную информацию. Это создаст несколько переменных с иллюзией массива:
@echo off
setlocal enabledelayedexpansion
SET var[0]=A
SET var[1]=foo bar
SET var[2]=123
for %%a in (0,1,2) do (
echo !var[%%a]!
)
echo Get one of the variables directly: %var[1]%
Результат:
A
foo bar
123
Get one of the variables directly: foo bar
Обратите внимание, что в приведенном выше примере вы не можете ссылаться на var не указывая, что такое желаемый индекс, потому что var не существует в своем собственном. Этот пример также использует setlocal enabledelayedexpansion в сочетании с восклицательными знаками в !var[%%a]! , Вы можете просмотреть дополнительную информацию об этом в документах с переменной заменой .
Операции над переменными
set var=10
set /a var=%var%+10
echo %var%
Конечное значение var равно 20.
Вторая строка не работает в командном блоке, используемом, например, в условии IF или в цикле FOR, поскольку требуется замедленное расширение вместо стандартного расширения переменной среды.
Вот еще один лучший способ работы в командном блоке:
set var=10
set /A var+=10
echo %var%
Среда командной строки поддерживает с подписанными 32-битными целыми значениями:
- дополнение
+и+= - вычитание
-и-= - умножение
*и*= - деление
/и/= - модульное деление
%и%= - побитовое И
& - побитовое ИЛИ
| - побитовое НЕ
~ - побитовое XOR
^ - побитовый сдвиг влево
<< - побитовый сдвиг вправо
>> - логическое НЕ
! - унарный минус
- - группировка с
(и)
Командный интерпретатор Windows не поддерживает 64-разрядные целочисленные значения или значения с плавающей запятой в арифметических выражениях.
Примечание . Оператор % должен быть записан в пакетном файле как %% который должен интерпретироваться как оператор.
В окне командной строки, выполняющем set /A Value=8 % 3 командной строки set /A Value=8 % 3 присваивается значение 2 переменной среды Value и дополнительно выводится 2 .
В пакетном файле необходимо записать set /A Value=8 %% 3 чтобы присвоить значение 2 переменной окружения Value и ничего не выводится, соответственно, для обработки STDOUT (стандартный вывод). Набор строк set /A Value=8 % 3 в пакетном файле приведет к появлению сообщения об ошибке Отсутствует оператор при выполнении командного файла.
Для среды требуется коммутатор /A для арифметических операций, а не для обычных строковых переменных.
Каждая строка в арифметическом выражении после set /A означает, что число или оператор автоматически интерпретируются как имя переменной среды.
По этой причине ссылка на значение переменной с %variable% или !variable! не требуется, когда имя переменной состоит только из словных символов (0-9A-Za-z_), причем первый символ не является цифрой, что особенно полезно в командном блоке, начиная с ( и заканчивая сопоставлением ) .
Числа преобразуются из строки в целое число с функцией C / C ++ strtol с base , равной нулю, что означает автоматическое определение базы, что может легко привести к неожиданным результатам.
Пример:
set Divided=11
set Divisor=3
set /A Quotient=Divided / Divisor
set /A Remainder=Divided %% Divisor
echo %Divided% / %Divisor% = %Quotient%
echo %Divided% %% %Divisor% = %Remainder%
set HexValue1=0x14
set HexValue2=0x0A
set /A Result=(HexValue1 + HexValue2) * -3
echo (%HexValue1% + %HexValue2%) * -3 = (20 + 10) * -3 = %Result%
set /A Result%%=7
echo -90 %%= 7 = %Result%
set OctalValue=020
set DecimalValue=12
set /A Result=OctalValue - DecimalValue
echo %OctalValue% - %DecimalValue% = 16 - 12 = %Result%
Результат этого примера:
11 / 3 = 3
11 % 3 = 2
(0x14 + 0x0A) * -3 = (20 + 10) * -3 = -90
-90 %= 7 = -6
020 - 12 = 16 - 12 = 4
Переменные, не определенные при оценке арифметического выражения, заменяются значением 0.
Установка переменных из ввода
Используя переключатель /p с помощью команды SET вы можете определить переменные из ввода.
Этот вход может быть пользователем Вход (клавиатура):
echo Enter your name :
set /p name=
echo Your name is %name%
Который может быть упрощен следующим образом:
set /p name=Enter your name :
echo Your name is %name%
Или вы можете получить входные данные из файла:
set /p name=< file.txt
в этом случае вы получите значение первой строки из file.txt
Получение значения различной строки в файле:
(
set /p line1=
set /p line2=
set /p line3=
) < file.txt
Команда FOR задает запуск некоторой команды для каждого файла из заданного множества.
Работу команды for можно охарактеризовать так:
a) получение диапазона данных
b) присвоить переменной цикла for (например %%G) значение из диапазона данных
c) выполнить команду (иногда в команде участвует %%G, например, в качестве параметра)
d) выполнить шаги a), b), c), пока не будет достигнуто конечное значение из диапазона значений переменной цикла.
Очень хорошо команда for описана в справке w2k.
Синтаксис
for {% | %%}< переменная > in (< множество >) do < команда > [< ПараметрыКоманднойСтроки > ]
Параметры команды for следующие:
| Параметр | Описание |
| {%% | %}< переменная > | Обязательный элемент, который представляет замещаемое значение. Используйте один знак %, чтобы выполнить команду for из командной строки (не в командном файле). Два знака %% используются для команды for, выполняемой в составе командного файла (*.bat или *.cmd). Имена переменных чувствительны к регистру символов, и должны быть составлены из символов букв алфавита (например %a, %b или %c). |
| (< множество >) | Обязательный элемент, указывает на один или несколько файлов, каталогов или текстовых строк, или диапазон значений, по которому должна проходить итерация команды for. Наличие круглых скобок обязательно. |
| < команда > | Обязательный элемент, который указывает команду, выполняемого для каждого элемента множества (см. предыдущий параметр). |
| ПараметрыКоманднойСтроки | Задает параметры командной строки, необходимые для использования с указанной командой (см. предыдущий параметр). |
| /? | Отображение справки в командной строке для команды for. |
Команду for можно использовать в командном файле (*.bat, *.cmd) или непосредственно запускать в командной строке.
Атрибуты. К команде for применяются перечисленные ниже атрибуты.
• В команде for переменная %переменная (или %%переменная) будет заменяться текстовой строкой из заданного параметра множество, пока параметр команда не обработает все файлы этого множества.
• Имена параметров переменная команды for учитывают регистр буквы, они являются глобальными, и одновременно может быть активно не больше 52 переменных.
• Для обозначения параметра переменная можно использовать любые знаки, кроме цифр 0–9, чтобы не было конфликта с параметрами пакетных файлов %0–%9. Для простых пакетных файлов вполне достаточно обозначений с одним знаком, например %%f.
• В сложных командных файлах могут быть использованы и другие обозначения для параметра переменная.
Задание множества файлов. Параметр множество может представлять группу файлов или несколько групп файлов. Для задания групп файлов можно использовать подстановочные знаки (* и ?). Следующие множества файлов являются допустимыми:
(*.doc)
(*.doc *.txt *.me)
(jan*.doc jan*.rpt feb*.doc feb*.rpt)
(ar??1991.* ap??1991.*)
Когда используется команда for, первое значение в параметре множество заменяет параметр %переменная (или %%переменная), а затем для обработки этого значения выполняется указанная команда. Это продолжается до тех пор, пока не будут обработаны все файлы (или группы файлов), которые соответствуют значению параметра множество.
in и do. Ключевые слова in и do не являются параметрами, но они требуются для работы команды for. Если какое-то из этих слов пропущено, на экран будет выведено сообщение об ошибке.
Использование дополнительных форм команды for. Если расширения командного процессора разрешены (по умолчанию), то поддерживаются следующие дополнительные формы команды for.
• Только каталоги
Если параметр множество содержит подстановочные знаки (* и ?), команда, указанная в параметре команда, выполняется для каждого каталога (кроме множества файлов в указанном каталоге), совпадающего с параметром множество. Используется следующий синтаксис.
for /D {%% | %}переменная in (множество) do команда [ПараметрыКоманднойСтроки]
• Рекурсивная
Проходит по дереву каталогов с корнем в [диск:]путь, выполняя инструкцию for для каждого каталога в дереве. Если после ключа /R не задан каталог, предполагается текущий каталог. Если параметр множество задан одной точкой (.), то команда просто перечислит каталоги в дереве. Используется следующий синтаксис.
for /R [[диск:]путь] {%% | %}переменная in (множество) do команда [ПараметрыКоманднойСтроки]
• Итерация диапазона значений
Используйте переменную итерации для установки начального значения (НачальноеЗначение#), а затем перемещайтесь по диапазону значений, пока значение не превысит конечное значение множества (КонечноеЗначение#). /L выполнит итерацию, сравнив параметр НачальноеЗначение# с параметром КонечноеЗначение#. Если параметрНачальноеЗначение# меньше параметра КонечноеЗначение#, то выполняется команда. Когда переменная итерации превысит параметр КонечноеЗначение#, командная оболочка покидает цикл. Также можно использовать отрицательный параметр шаг# для перемещения в диапазоне убывающих значений. Например, (1,1,5) создает последовательность «1 2 3 4 5», а (5,-1,1) создает последовательность «5 4 3 2 1». Используется следующий синтаксис.
for /L {%% | %}переменная in (НачальноеЗначение#,шаг#,КонечноеЗначение#) do команда [ПараметрыКоманднойСтроки]
• Итерация и разбор файлов
Разбор файлов следует использовать для обработки вывода команды, строк и содержимого файла. Используйте переменные итерации для определения содержимого или строк, которые требуется проверить. Параметр КлючевыеСловаРазбора используется для изменения разбора. Используйте параметр маркера КлючевыеСловаРазбора для указания маркеров, которые воспринимаются как переменные итерации. Примечание. Без параметра маркера ключ /F проверяет только первый маркер.
Разбор файлов состоит в чтении вывода, строки или содержимого файла, разбиении его на отдельные строки текста и разборе каждой строки на ноль или маркеры. Цикл программы for затем вызывается с переменной итерации, установленной в маркер. По умолчанию /F передает первый отделенный пробелом элемент из каждой строки каждого файла. Пустые строки пропускаются. Используется также другой синтаксис.
for /F [«КлючевыеСловаРазбора»] {%% | %}переменная lin (МножествоИменФайлов) do команда [ПараметрыКоманднойСтроки]
for /F [«КлючевыеСловаРазбора»] {%% | %}переменная in («СимвольнаяСтрока») do команда [ПараметрыКоманднойСтроки]
for /F [«КлючевыеСловаРазбора»] {%% | %}переменная in (‘команда’) do команда [ПараметрыКоманднойСтроки]
Аргумент МножествоИменФайлов задает одно или несколько имен файлов. Каждый файл открывается, считывается и обрабатывается до перехода к следующему файлу параметра МножествоИменФайлов. Чтобы переопределить стандартное поведение разбора, укажите параметр «КлючевыеСловаРазбора». Это строка, заключенная в кавычки, которая содержит одно или несколько ключевых слов для указания различных режимов разбора.
Если используется параметр usebackq, используйте один из приведенных ниже синтаксисов:
for /F [«usebackqКлючевыеСловаРазбора»] {%% | %}переменная in («МножествоИменФайлов») do команда [ПараметрыКоманднойСтроки]
for /F [«usebackqКлючевыеСловаРазбора»] {%% | %}переменная in (‘СимвольнаяСтрока’) do команда [ПараметрыКоманднойСтроки]
for /F [«usebackqКлючевыеСловаРазбора»] {%% | %}переменная in (‘команда’) do команда [ПараметрыКоманднойСтроки]
В приведенной ниже таблице перечислены ключевые слова разбора, которые используются для параметра КлючевыеСловаРазбора.
| Ключевое слово | Описание |
| eol=c | Задает символ конца строки (только один символ). |
| skip=N | Задает число строк, пропускаемых в начале файла. |
| delims=xxx | Задает набор разделителей. Заменяет набор разделителей по умолчанию, состоящий из пробела и символа табуляции. |
| tokens=X,Y,M-N | Задает элементы, передаваемые из каждой строки в тело цикла for при каждой итерации. В результате размещаются дополнительные имена переменных. Форма M-N задает диапазон, указывающий элементы с M-го по N-ый. Если последним символом строки tokens= является звездочка (*), то размещается дополнительная переменная, в которую помещается остаток строки после разбора последнего элемента. |
| usebackq | Задает возможность использования кавычек для имен файлов в параметре МножествоИменФайлов. Задает исполнение строки, заключенной в обратные кавычки, как команды, а строки в одиночных кавычках — как команды в символьной строке. |
• Подстановка переменных
Были расширены модификаторы подстановок для ссылок на переменные в for. Приведенная ниже таблица перечисляет варианты синтаксических конструкций (на примере переменной I).
| Переменная с модификатором | Описание |
| %~I | Расширение %I, которое удаляет окружающие кавычки («»). |
| %~fI | Расширение %I до полного имени пути. |
| %~dI | Замена %I именем диска. |
| %~pI | Замена %I на путь. |
| %~nI | Замена %I одним именем файла. |
| %~xI | Замена %I расширением имени файла. |
| %~sI | Замена путем, содержащим только короткие имена. |
| %~aI | Замена %I атрибутами файла. |
| %~tI |
Замена %I временем модификации файла. |
| %~zI | Замена %I размером файла. |
| %~$PATH:I | Поиск в каталогах, перечисленных в переменной среды PATH, и замена %I полным именем первого найденного файла. Если переменная среды не определена или поиск не обнаружил файлов, модификатор выдает пустую строку. |
Приведенная ниже таблица перечисляет комбинации модификаторов, которые можно использовать для получения более сложных результатов.
| Переменная с объединенными модификаторами | Описание |
| %~dpI | Замена %I именем диска и путем. |
| %~nxI | Замена %I именем файла и расширением. |
| %~fsI | Замена %I полным именем пути с короткими именами. |
| %~dp$PATH:I | Поиск в каталогах, перечисленных в переменной среды PATH, и замена %I именем диска и путем первого найденного файла. |
| %~ftzaI | Замена %I строкой, аналогичной результату работы команды dir. |
В приведенных выше примерах %I и PATH могут быть заменены другими допустимыми значениями. Допустимое имя переменной for прекращает синтаксис %~.
Использование прописных букв в именах переменных, например %I, может улучшить восприятие программы и позволит избежать недоразумений с модификаторами, в которых строчные и прописные буквы не различаются.
Разбор строки. Конструкция for /F может быть использована непосредственно для строки. Для этого поместите параметр МножествоИменФайлов между скобками в одиночные кавычки (‘МножествоИменФайлов’). Параметр МножествоИменФайлов будет воспринят как одиночная строка ввода из файла и будет разобран.
Разбор вывода. Команду for /F можно использовать для разбора вывода команды. Для этого поместите параметр МножествоИменФайлов между скобками в обратные кавычки. Он будет воспринят как командная строка, которая передается дочернему интерпретатору командной строки Cmd.exe, а результаты работы команды помещаются в памяти и разбираются, как если бы они являлись файлом.
[Примеры]
В пакетных файлах используется следующий синтаксис для команды for:
for %%переменная in (множество) do команда [ПараметрыКоманднойСтроки]
Чтобы отобразить содержимое всех файлов, имеющих разрешение DOC или TXT, в текущем каталоге с помощью заменяемой переменной %f, введите следующую команду:
for %%f in (*.doc *.txt) do type %%f
В предыдущем примере каждый файл с расширением .doc или .txt в текущем каталоге будет подставляться вместо переменной %f, пока не будет выведено содержимое всех файлов. Для использования этой команды в пакетном файле нужно заменить каждую команду %f на %%а. В противном случае переменная игнорируется и выводится сообщение об ошибке.
Чтобы произвести разбор файла, игнорируя комментарии, можно использовать следующую команду:
for /F «eol=; tokens=2,3* delims=,» %i in (myfile.txt) do @echo %i %j %k
Данная команда производит разбор каждой строки в файле Myfile.txt, игнорируя строки, начинающиеся с точки с запятой, и передает второй и третий элементы из каждой строки в тело цикла команды FOR. Элементы разделяются запятыми или пробелами. Тело инструкции FOR использует %i для получения второго элемента, %j для получения третьего элемента и %k для получения оставшихся элементов в строке. Если имена файлов содержат пробелы, их следует заключать в кавычки (например, «ИмяФайла»). Для использования кавычек необходима команда usebackq. В противном случае кавычки рассматриваются как определение символьной строки для разбора.
Переменная %i объявлена явно в инструкции FOR. Переменные %j и %k объявлены явно при использовании tokens=. С помощью tokens= можно указать до 26 элементов, если это не вызовет попытки объявить переменную с именем, большим буквы «z» или «Z».
Для разбора вывода команды с помощью помещения параметра МножествоИменФайлов в скобки можно использовать следующую команду (пример выводит список имен всех переменных окружения):
for /F «usebackq delims==» %i IN (`set`) DO @echo %i
Ищем в директориях файлы с расширением html содержащие строку google:
for /R %%f in (*.html) do @findstr /m «google» %%f
FOR /L
выполнить команду для диапазона чисел
Синтаксис
FOR /L %%parameter IN (start,step,end) DO command
Где
start первое число (включительно)
step инкремент числа для каждого шага
end последнее число (включительно)
command выполняемая команда, здесь же указываются параметры командной строки для неё
%%parameter изменяемый при каждой прокрутке цикла параметр (переменная цикла)
Внутри командного файла в качестве параметра используйте %%G, а в командной строке %G (такие уж Микрософт придумал правила). (20,-5,10) будет генерить последовательность 20 15 10, а (1,1,5) последовательность 1 2 3 4 5.
Пример
FOR /L %%G IN (1,1,5) DO echo %%G
Можно использовать нечисловой список, например:
FOR %%G IN (Sun Mon Tue Wed Thur Fri Sat) DO echo %%G
[Другие команды for]
FOR — цикл по всем файлам в одной директории (исключая её подкаталоги)
FOR /R — цикл по всем файлам, включая подкаталоги
FOR /D — цикл через несколько папок
FOR /F — цикл через слова в текстовом файле или через вывод команды
syntax-FOR-Files
FOR %%parameter IN (set) DO command
syntax-FOR-Files-Rooted at Path
FOR /R [[drive:]path] %%parameter IN (set) DO command
syntax-FOR-Folders
FOR /D %%parameter IN (folder_set) DO command
syntax-FOR-List of numbers
FOR /L %%parameter IN (start,step,end) DO command
syntax-FOR-File contents
FOR /F [«options»] %%parameter IN (filenameset) DO command
FOR /F [«options»] %%parameter IN («Text string to process») DO command
syntax-FOR-Command Results
FOR /F [«options»] %%parameter IN (‘command to process’) DO command
[Связанные с for команды]
FORFILES (w2003 Server) — выборка списка файлов из директории для отображения или использования при обработке в bat-файле
GOTO метка — прямой переход на строку в командном файле, помеченную строкой :метка
IF — условное выполнение команды
[Equivalent Linux BASH commands]
for — Expand words, and execute commands
case — Conditionally perform a command
eval — Evaluate several commands/arguments
if — Conditionally perform a command
gawk — Find and Replace text within file(s)
m4 — Macro processor
until — Execute commands (until error)
while — Execute commands
[Условные обозначения форматирования]
| Формат | Описание |
| Курсив | Сведения, вводимые пользователем |
| Полужирный шрифт | Элементы, вводимые без изменений |
| Многоточие (…) | Параметр может быть введен в командной строке несколько раз |
| В квадратных скобках ([]) | Необязательные элементы |
| В фигурных скобках ({}), варианты, разделенные вертикальной линией (|). Пример: {even|odd} | Набор вариантов, из которых необходимо выбрать один |
| Courier font | Программа или выходные данные |
[Ссылки]
1. Практические приемы программирования в bat-файлах.
- Overview
- Part 1 – Getting Started
- Part 2 – Variables
- Part 3 – Return Codes
- Part 4 – stdin, stdout, stderr
- Part 5 – If/Then Conditionals
- Part 6 – Loops
- Part 7 – Functions
- Part 8 – Parsing Input
- Part 9 – Logging
- Part 10 – Advanced Tricks
Today we’ll cover variables, which are going to be necessary in any non-trivial batch programs. The syntax for variables can be a bit odd,
so it will help to be able to understand a variable and how it’s being used.
Variable Declaration
DOS does not require declaration of variables. The value of undeclared/uninitialized variables is an empty string, or "". Most people like this, as
it reduces the amount of code to write. Personally, I’d like the option to require a variable is declared before it’s used, as this catches
silly bugs like typos in variable names.
Variable Assignment
The SET command assigns a value to a variable.
SET foo=bar
NOTE: Do not use whitespace between the name and value; SET foo = bar will not work but SET foo=bar will work.
The /A switch supports arthimetic operations during assigments. This is a useful tool if you need to validated that user input is a numerical value.
SET /A four=2+2
4
A common convention is to use lowercase names for your script’s variables. System-wide variables, known as environmental variables, use uppercase names. These environmental describe where to find certain things in your system, such as %TEMP% which is path for temporary files. DOS is case insensitive, so this convention isn’t enforced but it’s a good idea to make your script’s easier to read and troubleshoot.
WARNING: SET will always overwrite (clobber) any existing variables. It’s a good idea to verify you aren’t overwriting a system-wide variable when writing a script. A quick ECHO %foo% will confirm that the variable foo isn’t an existing variable. For example, it might be tempting to name a variable “temp”, but, that would change the meaning of the widely used “%TEMP%” environmental varible. DOS includes some “dynamic” environmental variables that behave more like commands. These dynamic varibles include %DATE%, %RANDOM%, and %CD%. It would be a bad idea to overwrite these dynamic variables.
Reading the Value of a Variable
In most situations you can read the value of a variable by prefixing and postfixing the variable name with the % operator. The example below prints the current value of the variable foo to the console output.
C:\> SET foo=bar
C:\> ECHO %foo%
bar
There are some special situations in which variables do not use this % syntax. We’ll discuss these special cases later in this series.
Listing Existing Variables
The SET command with no arguments will list all variables for the current command prompt session. Most of these varaiables will be system-wide environmental variables, like %PATH% or %TEMP%.
NOTE: Calling SET will list all regular (static) variables for the current session. This listing excludes the dynamic environmental variables like %DATE% or %CD%. You can list these dynamic variables by viewing the end of the help text for SET, invoked by calling SET /?
Variable Scope (Global vs Local)
By default, variables are global to your entire command prompt session. Call the SETLOCAL command to make variables local to the scope of your script. After calling SETLOCAL, any variable assignments revert upon calling ENDLOCAL, calling EXIT, or when execution reaches the end of file (EOF) in your script.
This example demonstrates changing an existing variable named foo within a script named HelloWorld.cmd. The shell restores the original value of %foo% when HelloWorld.cmd exits.
A real life example might be a script that modifies the system-wide %PATH% environmental variable, which is the list of directories to search for a command when executing a command.
Special Variables
There are a few special situations where variables work a bit differently. The arguments passed on the command line to your script are also variables, but, don’t use the %var% syntax. Rather, you read each argument using a single % with a digit 0-9, representing the ordinal position of the argument.
You’ll see this same style used later with a hack to create functions/subroutines in batch scripts.
There is also a variable syntax using !, like !var!. This is a special type of situation called delayed expansion.
You’ll learn more about delayed expansion in when we discuss conditionals (if/then) and looping.
Command Line Arguments to Your Script
You can read the command line arguments passed to your script using a special syntax. The syntax is a single % character followed by the ordinal position of the argument from 0 – 9. The zero ordinal argument is the name of the batch file itself. So the variable %0 in our script HelloWorld.cmd will be “HelloWorld.cmd”.
The command line argument variables are
* %0: the name of the script/program as called on the command line; always a non-empty value
* %1: the first command line argument; empty if no arguments were provided
* %2: the second command line argument; empty if a second argument wasn’t provided
* …:
* %9: the ninth command line argument
NOTE: DOS does support more than 9 command line arguments, however, you cannot directly read the 10th argument of higher. This is because the special variable syntax doesn’t recognize %10 or higher. In fact, the shell reads %10 as postfix the %0 command line argument with the string “0”. Use the SHIFT command to pop the first argument from the list of arguments, which “shifts” all arguments one place to the left. For example, the the second argument shifts from position %2 to %1, which then exposes the 10th argument as %9. You will learn how to process a large number of arguments in a loop later in this series.
Tricks with Command Line Arguments
Command Line Arguments also support some really useful optional syntax to run quasi-macros on command line arguments that are file paths. These macros
are called variable substitution support and can resolve the path, timestamp, or size of file that is a command line argument. The documentation for
this super useful feature is a bit hard to find – run ‘FOR /?’ and page to the end of the output.
%~Iremoves quotes from the first command line argument, which is super useful when working with arguments to file paths. You will need to quote any file paths, but, quoting a file path twice will cause a file not found error.
SET myvar=%~I
-
%~fIis the full path to the folder of the first command line argument -
%~fsIis the same as above but the extrasoption yields the DOS 8.3 short name path to the first command line argument (e.g.,C:\PROGRA~1is
usually the 8.3 short name variant ofC:\Program Files). This can be helpful when using third party scripts or programs that don’t handle spaces
in file paths. -
%~dpIis the full path to the parent folder of the first command line argument. I use this trick in nearly every batch file I write to determine
where the script file itself lives. The syntaxSET parent=%~dp0will put the path of the folder for the script file in the variable%parent%. -
%~nxIis just the file name and file extension of the first command line argument. I also use this trick frequently to determine the
name of the script at runtime. If I need to print messages to the user, I like to prefix the message with the script’s name, like
ECHO %~n0: some messageinstead ofECHO some message. The prefixing helps the end user by knowing the output is
from the script and not another program being called by the script. It may sound silly until you spend hours trying to track down
an obtuse error message generated by a script. This is a nice piece of polish
I picked up from the Unix/Linux world.
Some Final Polish
I always include these commands at the top of my batch scripts:
SETLOCAL ENABLEEXTENSIONS
SET me=%~n0
SET parent=%~dp0
The SETLOCAL command ensures that I don’t clobber any existing variables after my script exits. The ENABLEEXTENSIONS argument turns on a very
helpful feature called command processor extensions. Trust me, you want command processor extensions. I also store the name of the script
(without the file extension) in a variable named %me%; I use this variable as the prefix to any printed messages (e.g. ECHO %me%: some message).
I also store the parent path to the script in a variable named %parent%. I use this variable to make fully qualified filepaths to any
other files in the same directory as our script.
<< Part 1 – Getting Started
Part 3 – Return Codes >>
1. Overview of loops in Batch language
-
Space
-
Comma ( , )
-
Semi-colon ( ; )
-
TAB
2. For Loop (Default)
For loop (default) of Batch language is used to iterate over a list of files.
Syntax:
@rem set_of_files - Set of Files
@rem Files separated by standard delimiters.
@rem The parameter name 'variable' must be 1 character
FOR %%variable IN ( set_of_files ) DO command
@rem Hoặc:
FOR %%parameter IN ( set_of_files ) DO (
command
)
Example: copy some files into a directory (Note: the files to be copied into the target directory need to be in the same disk drive).
copyFiles.bat
@echo off
@rem Copy to same Disk
FOR %%f IN (E:\test\file1.data E:\test\file2.txt) DO (
echo Copying %%f
copy %%f E:\backup
)
pause
Other example:
@rem The delimiter is a semicolon (;)
FOR %%f IN ("E:\my dir\file1.data" ; E:\test\file2.txt) DO copy %%f E:\backup
@rem The delimiter is a comma ( , )
FOR %%f IN ("E:\my dir\file1.data" , E:\test\file2.txt) DO copy %%f E:\backup
@rem The delimiter is a space.
FOR %%f IN ("E:\my dir\file1.data" E:\test\file2.txt) DO copy %%f E:\backup
3. For /R
The FOR /R loop is used to iterate over the list of files, including files in subdirectories, grandchildren .. It is called Recurse loop.
Syntax:
FOR /R [path] %%variable IN ( set_of_file_filters ) DO command
@rem Or:
FOR /R [path] %%variable IN ( set_of_file_filters ) DO (
command
)
-
[path] : This parameter is a root folder. If there is not this parameter «the folder containing executable script file» hoặc «current folder» will be considered as root folder .
-
set_of_file_filters : List of file filters, for example *.txt , *.bat, … or dot ( . ) means all.
-
variable: means name of variable and must have one unique characte.
The following example prints the list of all *.txt or *.log files in the C:/Windows/System32 directory (Includes search in subdirectories, grandchildren ..)
forR_example1.bat
@echo off
FOR /R "C:\Windows\System32" %%f IN (*.txt *.log) DO (
echo %%f
)
pause
Example of listing all files in the C:/Windows/System32 directory (including files in subdirectories, grandchildren …)
forR_example2.bat
@echo off
FOR /R "C:\Windows\System32" %%f IN ( . ) DO (
echo %%f
)
pause
4. For /D
The FOR /D loop is used to iterate over the list of directories which are subdirectories of current directory.
Syntax:
FOR /D [/r] %%variable IN ( set_of_directory_filters ) DO command
@rem Or:
FOR /D [/r] %%parameter IN ( set_of_directory_filters ) DO (
command
)
-
set_of_directory_filters : List of directory filters for example, en*, fr*,.. separated by a standard delimiter.
-
[/r]: This is a recurse parameter and not mandatory. If this parameter is available, subdirectories, grandchildren .. will be envolved in the loop.
-
variable: means name of variable and must have a unique character.
Example: List subdirectories of C:/Windows.
forD_example1.bat
@echo off
C:
cd C:/Windows
FOR /D %%d IN ( * ) DO (
echo %%d
)
pause
Example: List subdirectories, grandchildren … of the C:/Windows with the name started by «en» or «fr»
forD_example2.bat
@echo off
C:
cd C:/Windows
FOR /D /r %%d IN (en* fr*) DO (
echo %%d
)
pause
5. For /L
For /L loop is used to iterate over a range of numbers.
Syntax:
FOR /L %%variable IN (start, step, end) DO command
@rem Or:
FOR /L %%variable IN (start, step, end) DO (
command
)
-
start: The first value of variable
-
step: After each iteration, variable value will be added ‘step’.
-
end: Last value.
Example:
forL_example1.bat
@echo off
FOR /L %%d IN (1 2 8 ) DO (
echo %%d
)
pause
forL_example2.bat
@echo off
FOR /L %%d IN (20 -2 5 ) DO (
echo %%d
)
pause
6. For /F
The For /F loop is a complex but powerful loop. It reads a file or a few files and then analyzes the contents of files. The content of a file is a text; it is split into several small pieces of text, each of which is called a Token. The default rule for separating a text is based on white space. However, you can customize the delimiter rule by [«delims = xxx»] parameter.
The For / F loop is also used to analyze the contents of a string, or to execute a set of commands.
Syntax:
FOR /F ["options"] %%variable IN ( set_of_filenames ) DO command
FOR /F ["options"] %%variable IN ( set_of_filenames ) DO (
command
)
FOR /F ["options"] %%variable IN ("Text string to process") DO command
FOR /F ["options"] %%variable IN ("Text string to process") DO (
command
)
-
set_of_filenames: List of a or several files.
-
options: Options, for example, «delims=, tokens=1,2,4»
|
Option |
Description |
|
delims=xxx |
Delimiter character(s). by default is a space |
|
skip=n |
The first line number will be ignored in the contents of file, defaulted skip = 0 |
|
eol=; |
eol (End of Line): Specifies a special character, which is put at the beginning of a line to mark this line as comment line. Comment lines will be ignored by the program, defaulted semicolon character (;) |
|
tokens=n1,n2,n3 |
defines the positions cared about (n1, n2, n3, ..), defaulted tokens=1 |
|
usebackq |
(See explanation in examples) |
To be easy to understand, let’s analyze the following file:
eol (End of Line)
eol: Used to specify a special character, which is by default a semicolon character (;). It is placed at the beginning of a line to mark that such line is a comment. The program will ignore this line.
skip=n
skip: Declare the number of first lines of the file will be ignored, the program will not analyze these lines. Default skip = 0
delims (Delimiter character(s))
delims: Defines delimiter characters, helping the program to delimit each line of text into sub-paragraphs, each of which is called a Token. Tokens are marked indices: 1, 2, 3, …
tokens=n1,n2,n3
tokens: Declare a list of indices that are interested in, separated by commas. For example, tokens = 1,2,4, defaulted: tokens = 1
|
The indices such as 1, 2, 4 are interested. |
|
|
The indices of 2 to 8 are interested |
|
|
The indices such as 3, 4,5, … are interested |
|
|
All indices are interested |
For example, «tokens=1,2,4», means that Tokens at the position of 1, 2, 4 are interested and other Tokens will be ignored.
Example of file analysis:
Example of using the FOR /F loop to read persons.txt file:
persons.txt
List of celebrities
Creation date: 2017/09/11
; (Comment) Male List
Bill,Gates,1955/10/28,Male
Steve,Jobs,1955/02/24,Male
Mark,Zuckerberg,1984/05/16,Male
Sundar,Pichai,1972/07/12,Male
; (Comment) Female List
Hillary,Clinton,1947/10/26,Female
forF_example1.bat
@echo off
FOR /F "delims=, skip=3 eol=; tokens=1,2,4" %%i IN ( persons.txt ) DO (
echo Full Name: %%i %%j Gender: %%k
)
pause
Note: Name of variables on the loop has only character .
Biến %%i variable is explicitly declared on the loop. %% j, %% k variables are implicitly declared (names of implicit variables are the next characters of explicit variable names).
Example of String analysis:
-
TODO
