Замечание. Иногда более удобным для работы с кодами завершения программ может оказаться использование переменной
%ERRORLEVEL%
(строковое представление текущего значения кода ошибки
ERRORLEVEL
).
1.1.13 Организация циклов
В командных файлах для организации циклов используются несколько разновидностей оператора
FOR
, которые обеспечивают следующие функции:
выполнение заданной команды для всех элементов указанного множества;
выполнение заданной команды для всех подходящих имен файлов;
выполнение заданной команды для всех подходящих имен каталогов;
выполнение заданной команды для определенного каталога, а также всех его подкаталогов;
получение последовательности чисел с заданными началом, концом и шагом приращения;
чтение и обработка строк из текстового файла;
обработка строк вывода определенной команды.
1.1.13.1 Цикл FOR … IN … DO …
Самый простой вариант синтаксиса команды
FOR
для командных файлов имеет следующий вид:
42
FOR %%переменная IN (множество)
DO команда [параметры]
Внимание!
Перед названием переменной должны стоять именно два знака процента
(%%)
, а не один, как это было при использовании команды
FOR
непосредственно из командной строки!
Пример 5. Если в командном файле заданы строки
@ECHO OFF
FOR %%i IN (Раз, Два, Три) DO ECHO %%i то в результате его выполнения на экран будет выведено следующее:
Раз
Два
Три
Параметр множество в команде FOR задает одну или более текстовых строк, разделенных запятыми, которые необходимо обработать с помощью заданной команды. Скобки здесь обязательны. Параметр команда [параметры]
задает команду, выполняемую для каждого элемента множества, при этом вложенность команд
FOR
на одной строке
не допускается. Если в строке, входящей во множество, используется запятая, то значение этой строки нужно заключить в кавычки. Например, в результате выполнения файла с командами
@ECHO OFF
FOR %%i IN ("Раз,Два",Три) DO ECHO %%i на экран будет выведено
Раз,Два
Три
Параметр
%%переменная представляет подставляемую переменную (счетчик цикла), причем здесь могут использоваться только имена переменных, состоящие из одной буквы. При выполнении команда
FOR
заменяет подставляемую переменную текстом каждой строки в заданном множестве, пока команда, стоящая после ключевого слова
DO
, не обработает все такие строки.
Замечание. Чтобы избежать путаницы с параметрами командного файла
%0 — %9, для переменных следует использовать любые символы кроме 0
– 9.
Параметр множество в команде FOR может также представлять одну или несколько групп файлов. Например, чтобы вывести в файл список всех файлов с расширениями txt и prn, находящихся в каталоге C:\TEXT, без использования команды DIR, можно использовать командный файл следующего содержания:
@ECHO OFF
43
FOR %%f IN (C:\TEXT\*.txt C:\TEXT\*.prn) DO ECHO %%f >> list.txt
При таком использовании команды FOR процесс обработки продолжается, пока не обработаются все файлы (или группы файлов), указанные во множестве.
1.1.13.2 Цикл FOR /D … IN … DO …
Следующий вариант команды
FOR
реализуется с помощью ключа /D
(directory – каталог):
FOR /D %переменная IN (набор) DO команда [параметры]
В случае, если набор содержит подстановочные знаки, то команда выполняется для всех подходящих имен каталогов, а не имен файлов.
Скажем, выполнив следующий командный файл:
@ECHO OFF
CLS
FOR /D %%f IN (C:\*.*) DO ECHO %%f мы получим список всех каталогов на диске C:, например:
C:\Arc
C:\CYR
C:\MSCAN
C:\Program Files
C:\TEMP
C:\WINNT
1.1.13.3 Цикл FOR /R … IN … DO …
С помощью ключа
/R
можно задать рекурсию в команде
FOR
:
FOR /R [[диск:]путь] %переменная IN (набор)
DO команда [параметры]
В этом случае заданная команда выполняется для каталога
[диск:]путь
, а также для всех подкаталогов этого пути. Если после ключа
R
не указано имя каталога, то выполнение команды начинается с текущего каталога.
Пример 6. Для распечатки всех файлов с расширением txt в текущем каталоге и всех его подкаталогах можно использовать следующий пакетный файл:
@ECHO OFF
CLS
FOR /R %%f IN (*.txt) DO PRINT %%f
Если вместо набора указана только точка (.), то команда проверяет все подкаталоги текущего каталога. Например, если мы находимся в каталоге C:\TEXT с двумя подкаталогами BOOKS и ARTICLES, то в результате выполнения файла:
@ECHO OFF
CLS
44
FOR /R %%f IN (.) DO ECHO %%f на экран выведутся три строки:
C:\TEXT\.
C:\TEXT\BOOKS\.
C:\TEXT\ARTICLES\.
1.1.13.4 Цикл FOR /L … IN … DO … Ключ
/L
позволяет реализовать с помощью команды
FOR
цикл со счетчиком, в этом случае синтаксис имеет следующий: вид:
FOR /L %переменная IN (начало,шаг,конец) DO команда [параметры]
Здесь заданная после ключевого слова
IN
тройка (начало, шаг, конец) задает последовательность чисел с заданными началом, концом и шагом приращения. Например, тройка (1, 1, 5) порождает последовательность (1 2 3 4 5), а тройка (5, -1, 1) - последовательность (5 4 3 2 1). Например, в результате выполнения следующего командного файла:
@ECHO OFF
CLS
FOR /L %%f IN (1,1,5) DO ECHO %%f переменная цикла
%%f получит значения от 1 до 5, и на экран будут выведены пять чисел:
1 2
3 4
5
Числа, получаемые в результате выполнения цикла
FOR /L
, можно использовать в
арифметических вычислениях. Рассмотрим командный файл my.bat следующего содержания:
@ECHO OFF
CLS
FOR /L %%f IN (1,1,5) DO CALL :2 %%f
GOTO :EOF
:2
SET /A M=10*%1
ECHO 10*%1=%M%
В третьей строке в цикле происходит вызов нового контекста файла my.bat с текущим значением переменной цикла
%%f в
качестве параметра командной строки, причем управление передается на метку
:2
(см. описание
CALL
в разделе "Изменения в командах перехода"). В шестой строке переменная цикла умножается на десять, и результат записывается в переменную
M
. Таким образом, в результате выполнения этого файла выведется следующая информация:
45 10*1=10 10*2=20 10*3=30 10*4=40 10*5=50
1.1.13.5 Цикл FOR /F … IN … DO …
Самые широкие возможности имеет команда
FOR
с ключом
/F
:
FOR /F ["ключи"] %переменная IN (набор) DO команда [параметры]
Здесь параметр набор содержит имена одного или нескольких файлов, которые по очереди открываются, читаются и обрабатываются.
Обработка состоит в чтении файла, разбиении его на отдельные строки текста и выделении из каждой строки заданного числа подстрок. Затем найденная подстрока используется в качестве значения переменной при выполнении основного тела цикла (заданной команды).
По умолчанию ключ
/F
выделяет из каждой строки файла первое слово, очищенное от окружающих его пробелов. Пустые строки в файле пропускаются. Необязательный параметр "ключи" служит для переопределения заданных по умолчанию правил обработки строк. Ключи представляют собой заключенную в кавычки строку, содержащую приведенные в (табл. 3) ключевые слова:
Таблица 3.
Ключи в команде FOR /F
Ключ
Описание
EOL=C
Определение символа комментариев в начале строки
(допускается задание только одного символа)
SKIP=N
Число пропускаемых при обработке строк в начале файла
DELIMS=XXX
Определение набора разделителей для замены заданных по умолчанию пробела и знака табуляции
TOKENS=X,Y,M-
N
Определение номеров подстрок, выделяемых из каждой строки файла и передаваемых для выполнения в тело цикла
При использовании ключа
TOKENS=X,Y,M-N
создаются дополнительные переменные. Формат
M-N
представляет собой диапазон подстрок с номерами от
M
до
N
. Если последний символ в строке
TOKENS=
является звездочкой, то создается дополнительная переменная, значением которой будет весь текст, оставшийся в строке после обработки последней подстроки.
46
Разберем применение этой команды на примере пакетного файла parser.bat, который производит разбор файла myfile.txt:
@ECHO OFF
IF NOT EXIST myfile.txt GOTO :NoFile
FOR /F "EOL=; TOKENS=2,3* DELIMS=, " %%i IN (myfile.txt) DO @ECHO
%%i %%j %%k
GOTO :EOF
:NoFile
ECHO Не найден файл myfile.txt!
Здесь во второй строке производится проверка наличия файла myfile.txt; в случае отсутствия этого файла выводится предупреждающее сообщение. Команда
FOR
в третьей строке обрабатывает файл myfile.txt следующим образом:
Пропускаются все строки, которые начинаются с символа точки с запятой (
EOL=;
).
Вторая и третья подстроки из каждой строки передаются в тело цикла, причем подстроки разделяются пробелами (по умолчанию) и/или запятыми (
DELIMS=,
).
В теле цикла переменная
%%i
используется для второй подстроки,
%%j
— для третьей, а
%%k получает все оставшиеся подстроки после третьей.
Замечание.Имена переменных i, j, k должны следовать в алфавитном порядке.
В нашем примере переменная
%%i явно описана в инструкции
FOR
, а переменные
%%j и
%%k описываются
неявно с помощью ключа
TOKENS=
Например, если в файле myfile.txt были записаны следующие три строки:
ААА BBBB CCCC,GGGG DDDD
ЕЕЕЕЕ,JJJJ KKKK
;TTTT LLLL МММММ то в результате выполнения пакетного файла parser.bat на экран выведется следующее:
BBBB CCCC GGGG DDDD
JJJJ KKKK
Замечание. Ключ
TOKENS=
позволяет извлечь из одной строки файла до
26 подстрок, поэтому запрещено использовать имена переменных, начинающиеся не с букв английского алфавита (a–z). Следует помнить, что имена переменных
FOR
являются
глобальными, поэтому одновременно не может быть активно более 26 переменных.
Команда FOR /F также позволяет обработать отдельную строку.
Для этого следует ввести нужную строку в кавычках вместо набора имен файлов в скобках. Строка будет обработана так, как будто она взята из файла. Например, файл следующего содержания:
47
@ECHO OFF
FOR /F "EOL=; TOKENS=2,3* DELIMS=, " %%i IN ("AA CC BB,GG DD")
DO @ECHO %%i %%j %%k при своем выполнении напечатает
CC BB GG DD
Вместо явного задания строки для разбора можно пользоваться переменными среды, например:
@ECHO OFF
SET M=ААА ББББ ВВВВ,ГГГГГ ДДДД
FOR /F "EOL=; TOKENS=2,3* DELIMS=,
" %%i IN ("%M%") DO @ECHO %%i %%j %%k
Наконец, команда
FOR /F
позволяет обработать строку вывода
другой команды. Для этого следует вместо набора имен файлов в скобках ввести строку вызова команды в апострофах (не в кавычках!). Строка передается для выполнения интерпретатору команд cmd.exe, а вывод этой команды записывается в память и обрабатывается так, как будто строка вывода взята из файла. Например, следующий командный файл:
@ECHO OFF
CLS
ECHO Имена переменных среды:
ECHO.
FOR /F "DELIMS==" %%i IN ('SET') DO ECHO %%i выведет перечень имен всех переменных среды, определенных в настоящее время в системе.
В цикле
FOR
допускается применение тех же синтаксических конструкций (операторов), что и для заменяемых параметров – (табл 4).
Таблица 4.
Операторы для переменных команды FOR
Операторы Описание
%Fi
Переменная %i расширяется до полного имени файла
%Di
Из переменной %i выделяется только имя диска
%Pi
Из переменной %i выделяется только путь к файлу
%Ni
Из переменной %i выделяется только имя файла
%Xi
Из переменной %i выделяется расширение имени файла
%Si
Значение операторов N и X для переменной %i изменяется так, что они работают с кратким именем файла
%Zi
Определяется длина (размер) файла с указанным именем
48
Замечание. Если планируется использовать расширения подстановки значений в команде
FOR
, то
следует внимательно подбирать имена переменных, чтобы они не пересекались с обозначениями формата.
Например, если мы находимся в каталоге C:\Program Files\Far и запустим командный файл следующего содержания:
@ECHO OFF
CLS
FOR %%i IN (*.txt) DO ECHO %%Fi то на экран выведутся полные имена всех файлов с расширением txt:
C:\Program Files\Far\Contacts.txt
C:\Program Files\Far\ReadMe.txt
C:\Program Files\Far\register.txt
C:\Program Files\Far\WhatsNew.txt
Вычисление суммарной длины всех файлов в заданном подкаталоге
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
Set /a Size = 0
For %%I in (%1\*.*) do set /a Size= Size + %%zI
Echo %Size%
1.1.13.6 Циклы и связывание времени выполнения для переменных Как и в рассмотренном выше примере с составными выражениями, при обработке переменных среды внутри цикла могут возникать труднообъяснимые ошибки, связанные с ранними связыванием переменных. Рассмотрим пример. Пусть имеется командный файл следующего содержания:
SET a=
FOR %%i IN (Раз,Два,Три) DO SET a=%a%%%i
ECHO a=%a%
В результате его выполнения на экран будет выведена строка "a=Три"
, то есть фактически команда
FOR %%i IN (Раз,Два,Три) DO SET a=%a%%%i равносильна команде
FOR %%i IN (Раз,Два,Три) DO SET a=%%i
Для исправления ситуации нужно, как и в случае с составными выражениями, вместо знаков процента (
%
) использовать восклицательные знаки и предварительно включить режим связывания времени выполнения командой
SETLOCAL ENABLEDELAYEDEXPANSION
. Таким образом, наш пример следует переписать следующим образом:
SETLOCAL ENABLEDELAYEDEXPANSION
SET a=
FOR %%i IN (One,Two,Three) DO SET a=!a!%%i
ECHO a=%a%
49
В этом случае на экран будет выведена строка "a=OneTwoThree"
1.1.13.7 Команда Findstr и ее использование в цикле
Назначение команды - поиск строк в текстовых файлах.
FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:файл]
[/C:строка] [/G:файл] [/D:список_папок] [/A:цвета] [/OFF[LINE]] строки [[диск:][путь]имя_файла[ ...]]
/L-Поиск строк дословно.
/R-Поиск строк как регулярных выражений.
/S-Поиск файлов в текущей папке и всех ее подпапках.
/I-Определяет, что поиск будет вестись без учета регистра.
/X-Печатает строки, которые совпадают точно.
/V-Печатает строки, не содержащие совпадений с искомыми.
/N-Печатает номер строки, в которой найдено совпадение, и ее содержимое.
/M-Печатает только имя файла, в которой найдено совпадение.
/O-Печатает найденный строки через пустую строку.
/P-Пропускает строки, содержащие непечатаемые символы.
/F:файл-Читает список файлов из заданного файла (/ для консоли).
/C:строка-Использует заданную строку как искомую фразу поиска.
/D:список_папок-Поиск в списке папок (разделяются точкой с запятой). строка Искомый текст.
[диск:][путь]имя_файла - задает имя файла или файлов.
Использовать пробелы для разделения нескольких искомых строк, если аргумент не имеет префикса /C. Например, 'FINDSTR "Привет мир" a.b' ищет "Привет" или "мир" в файле a.b, а команда 'FINDSTR /C:"Привет мир" a.b' ищет строку "Привет мир" в файле a.b.
Краткая сводка по синтаксису регулярных выражений:
. Любой символ.
* Повтор: ноль или более вхождений предыдущего символа или класса
^ Позиция в строке: начало строки
$ Позиция в строке: конец строки
[класс] Класс символов: любой единичный символ из множества
[^класс] Обратный класс символов: любой единичный символ из дополнения
[x-y] Диапазон: любые символы из указанного диапазона
\x Служебный символ: символьное обозначение служебного символа x
\ Позиция в слове: в конце слова
50
Пример командного файла для поиска в файле num.txt по образцу строк, в которых присутствует хотя бы одна двоичная цифра.
@echo off set /a kol=0 for /f %%b in ('findstr /rc:"[0-1]" num.txt') do set /a kol=kol+1 echo %kol%
2 МЕТОДИКА ВЫПОЛНЕНИЯ 1. Неформально ознакомиться с теоретическими сведениями.
2. Для подготовки текстов командных файлов рекомендуется использовать блокнот (Notepad). При этом следует избегать использования в выводимых на экран результатах работы командного файла букв русского алфавита.
3. Разработать и выполнить командные файлы (КФ), выполняющие следующие функции:
4. Вывод на экран имен всех файлов с указанным расширением, находящихся в каталоге, имя которого задается при запуске командного файла первым параметром. Расширение файлов задается вторым параметром.
5. Среди введенных с клавиатуры целых чисел (использовать SET /P) найти наибольшее и наименьшее. Признак конца ввода – знак -.
6. В заданном каталоге и его подкаталогах найти общее количество подкаталогов. На экран вывести только требуемый результат.
7. В каталогах, имена которых заданы первым и
вторым параметрами командного файла, найти и вывести на экран имена файлов
(расширения могут быть любые), присутствующие как в первом, так и во втором каталоге. Следует использовать только один оператор
FOR.
8. Вычисление и вывод на экран значения факториала целого числа, задаваемого при запуске КФ. Предусмотреть проверку заданного значения и при задании отрицательного значения или значения, превышающего максимально возможную величину, выводить соответствующие сообщения.
Для проверки правильности вычислений использовать калькулятор.
9. Разработать и выполнить КФ в соответствии с табл. 5
(индивидуальные задания для студентов).
51
Таблица 5.
Индивидуальные задания для бригад и студентов
Но- мер бри- гады
Действия, выполняемые КФ
1 1.Подсчет количества целых чисел в текстовом файле. Считать, что слова в файле записаны в формате ОДНО СЛОВО В СТРОКЕ.
Слово – это целое число (состоящее из десятичных цифр) или последовательность букв латинского алфавита (начинающаяся с буквы). Имя файла задается первым параметром КФ.
2. Вывод на экран списка файлов, хранящихся в указанном первым параметром каталоге и созданных в первом полугодии (месяцы 1-6) года, указанного вторым параметром КФ.
2
В каталоге, указанном первым параметром КФ, (и его подкаталогах) найти файл наибольшего размера с расширением, указанным вторым параметром КФ.
В каталоге, указанном первым параметром КФ, (и его подкаталогах) найти ТРИ файла самого большого размера. Вывести имена файлов, их размеры и даты создания
3 1. Разбиение текстового файла, имя которого задано первым параметром КФ, на три файла с именами 1.txt, 2.txt и 3.txt.
Количество строк в каждом из этих файлов задано вторым, третьим и четвертым параметрами КФ. Проверить наличие указанного исходного файла и вывести сообщение о его отсутствии, проверить наличие остальных параметров и их значения на допустимость
2. В каталоге, указанном первым параметром КФ, (и его подкаталогах) найти суммарный объем файлов, имеющих расширение, указанное вторым параметром КФ.
4 1. Удаление из каталога,
заданного первым параметром, файлов, которые присутствуют и в каталоге, указанным вторым параметром.
Предусмотреть запрос пользователю на подтверждение удаления.
2. В каталоге, указанном первым параметром КФ, и его подкаталогах, найти файлы, созданные во второй половине рабочего дня (после 14 часов) и скопировать их в отдельный подкаталог.
5
Нахождение суммарного объема файлов с атрибутом system, хранящихся в каталоге, имя которого задано первым параметром
КФ.
Проверить наличие файла Numb.txt в каталоге, указанном первым параметром КФ. Прочитать целые числа из файла, найти среди них простые и вывести результаты на экран. Считать, что все числа не превышают значения 2500.
6 1. Поиск на диске C: (или любом доступном диске) файла с
52
Но- мер бри- гады
Действия, выполняемые КФ заданным именем. Если файл не найден – вывод сообщения. Если файл найден – открыть его для редактирования.
2. Проверка наличия на диске в каталоге, указанном первым параметром КФ, файла FNames.txt, содержащего список имен файлов и подкаталогов. Если он есть – проверка наличия перечисленных в списке файлов и вывод имен отсутствующих. Если файла FNames нет, создание его и запись имен файлов и подкаталогов.
7 1. Вывод списка DLL (хранящихся на доступном диске), созданных до 12.2015 размером до 12000 байтов.
2. Проверка наличия на диске в каталоге, указанном первым параметром КФ, файла Numbers.txt, содержащего 2 столбца целых чисел, столбцы располагаются с позиций 2 и 20 и отделены пробелами. Если файла нет – вывод сообщения. Если файл есть, создать новый файл, содержащий три столбца, в третий поместить сумму чисел из двух первых столбцов.
8 1. Просмотр содержимого каталога, указанного первым параметром
КФ. Необходимо: 1. создать подкаталоги с именами EXE, TXT,
CMD, DOC и OTHER. 2. В каждый подкаталог скопировать файлы с соответствующими расширениями. 3. Пустые подкаталоги удалить.
2. В каталоге, указанном первым параметром КФ, (и его подкаталогах) найти файлы наибольшего и наименьшего размеров.
Вывести имена файлов, их размеры и даты создания.
9 1. Проверка наличия трех текстовых файлов на диске и объединения их в один файл.
2. Подсчет количества вещественных чисел и целых чисел в текстовом файле. Вещественные и целые числа подсчитать отдельно. Считать, что слова в файле записаны в формате ОДНО
СЛОВО В СТРОКЕ. Слово – это целое число (состоящее из десятичных цифр) или последовательность букв латинского алфавита (начинающаяся с буквы) или последовательность десятичных цифр с точкой (.) внутри строки. Имя файла задается первым параметром КФ.
10 1. Подсчет количества слов в текстовом файле, содержащем целые числа и слова. Считать, что слова в файле записаны в формате
ОДНО СЛОВО В СТРОКЕ. Число – это целое число (состоящее из десятичных цифр). Слово - последовательность букв латинского алфавита (начинающаяся с буквы). Имя файла задается первым параметром КФ.
53
Но- мер бри- гады
Действия, выполняемые КФ
2. Просмотр содержимого каталога, указанного первым параметром
КФ. Необходимо: 1. создать подкаталоги с именами 1, 2, ..., 12. 2. В каждый подкаталог скопировать файлы, созданные в соответствующие месяцы. 3. Пустые подкаталоги удалить.
11 1.
Подсчет количества строк в текстовом файле, имя которого задано первым параметром КФ. Проверить наличие указанного файла и вывести сообщение о его отсутствии.
2. С помощью команды DIR вывести на экран имена файлов, находящихся в каталоге, имя которого задано первым параметром
КФ. Второй и остальные параметры задают расширения файлов, имена которых выводить не следует. Рекомендуется с помощью
ATRIB присвоить некоторым файлам атрибут СКРЫТЫЙ – такие файлы DIR не показывает.
12 1.Поиск текстового файла по его содержимому. Считать, что слова в текстовых файлах записаны в формате ОДНО СЛОВО В СТРОКЕ.
Искомое слово задается первым параметром КФ.
13 1. Вывод на экран аргументов, с которыми КФ был запущен. Число аргументов от 4 до 11. При неверном числе аргументов ничего не выполнять, сообщить об ошибке.
2. Поиск и вывод на экран минимального и максимального значения аргумента КФ. Предполагается, что все аргументы КФ – целые положительные числа.
Примечание. Для решения задач 1, 9 и 10 рекомендуется использовать команду Findstr