- Сообщения
- 8,098
- Решения
- 21
- Реакции
- 6,899
Циклическиe операции FOR
Командой FOR задаётся список команд, которые выполняются с КАЖДЫМ элементом набора.
Набор* пишется внутри IN (...)
Список команд пишется внутри DO (...)
Командная строка выполняет эти команды раз за разом, при этом текущий элемент набора находится в переменной, заданной после %% (назовём ее переменной цикла).
Например,
выведет имена и путь ко всем файлам с расширением .txt в папке C:\Users.
* Примеры под спойлером
Ключ /F часто используется для построчного разбора файла, т.е.
выведет все строки файла 1.txt, который находится в корне диска C.
UseBackQ (Use back quotes) означает, что набор с двойными кавычками* подразумевает передачу в цикл имени файла.
delims= означает, что в переменную %%a будет записана вся строка (без разделения по пробелу или знаку табуляции, т.к. стандартный разделитель заменен на NULL (пустой символ).
В такой вариации:
tokens=* приводит к тому же результату, что и delims=. Означает прекратить разбивку по разделителю после "0-го" токена, т.е. сразу же.
* Этот вариант необходим для работы с файлом, путь или имя которого содержит пробелы.
Можно было не использовать UseBackQ, тогда команда приняла бы вид:
но такая конструкция восприняла бы пробел в имени как определение нового файла, поэтому UseBackQ более приемлем.
** Примеры под спойлером
Отличительной особенностью FOR /F является умение работать через токены*,
а также поддержка дополнительных ключевых слов:
1) eol - знак комментария в начале строки (1-й символ). Т.е. строки с таким символом не будут обрабатываться. (по умолчанию, знак точки с запятой ; )
2) skip - пропуск определенного кол-ва обрабатываемых строк от начала файла
3) delims - задать другой разделитель(-ли) (по умолчанию, пробел и знак табуляции)
4) tokens - количество получаемых токенов (подстрок) в теле цикла и пределы разбивки по разделителю.
Также можно задать конкретный № токена, который попадет в первую переменную цикла.
5) usebackq - изменение правил использования кавычек внутри IN (...)
Детальную справку можно получить, введя в консоль команду FOR /?
* Токены - это подстроки, которые попадают в переменные цикла %% в каждой из итераций.
Они получаются в результате разбивки строки, заданной в IN (...), по разделителю, заданному в Delims= (по умолчанию, пробел и знак табуляции).
В отличие, от FOR без ключа, в FOR /F все токены (все подстроки одной строки) попадают сразу В ПЕРВУЮ ИТЕРАЦИЮ цикла.
Они будут распределены по РАЗНЫМ переменным цикла, идущим в алфавитном порядке*, начиная с буквы, заданной после FOR /F %%
Т.е.
Результат:
Более универсальные конструкции на основе FOR /F для работы с файлами/папками строятся путем помещения
в IN ('...') команды, результаты от выполнения которой уж затем обрабатываются циклом.
Чаще всего это команда Dir.
Ключ /L
IN (первое, шаг, последнее)
означает математическое перечисление чисел от первого числа (0), до третьего (6), с шагом, указанным вторым числом (2) в наборе IN (...).
Указанная команда выведет:
Командой FOR задаётся список команд, которые выполняются с КАЖДЫМ элементом набора.
Набор* пишется внутри IN (...)
Список команд пишется внутри DO (...)
Командная строка выполняет эти команды раз за разом, при этом текущий элемент набора находится в переменной, заданной после %% (назовём ее переменной цикла).
Например,
Код:
FOR %%a IN (C:\Users\*.txt) DO echo %%a
* Примеры под спойлером
Для команды For без ключей набором может являться:
1) Маска файлов* (или путь + маска файлов)
- в двойных кавычках, или без них:
IN (*.txt)
Результат: список файлов с расширением .txt в текущем каталоге.
IN (*.txt *.bat)
Результат: список файлов с расширениеми .txt и .bat в текущем каталоге.
IN ("C:\Folder 1\Doc_31-12-*.txt")
Результат: тот же. Но поиск ведется в каталоге C:\Folder 1 (заметьте с пробелом в имени);
имя файла начинается на Doc_31-12-
Прим.: FOR без ключа не умеет выводить список каталогов.
* маска файлов - это набор файлов, заданный с помощью подстановочных знаков * и/или ?
где * - обозначает 0 или больше любых символов в имени файла.
а ? - означает 0 или 1 любой символ в имени файла.
2) Строка
- в двойных кавычках, или без них:
Строкой считается любая последовательность символов, если она не содержит знаков маски * или ?
Смысл цикла здесь в том, чтобы разбить такую строку по пробелам (или знакам табуляции)
и выполнить с каждой подстрокой список команд.
Результат:
Результат:
*О других модификаторах переменной цикла можно почитать здесь и здесь.
3) еще есть смешанный тип. Это когда в наборе стоит маска (1-й описанный тип), а через пробел Строка (2 тип)... ведет себя вполне ожидаемо, но вряд ли найдет себе применение.
О наборах для FOR с ключем /F далее в нижнем спойлере.
1) Маска файлов* (или путь + маска файлов)
- в двойных кавычках, или без них:
IN (*.txt)
Результат: список файлов с расширением .txt в текущем каталоге.
IN (*.txt *.bat)
Результат: список файлов с расширениеми .txt и .bat в текущем каталоге.
IN ("C:\Folder 1\Doc_31-12-*.txt")
Результат: тот же. Но поиск ведется в каталоге C:\Folder 1 (заметьте с пробелом в имени);
имя файла начинается на Doc_31-12-
Прим.: FOR без ключа не умеет выводить список каталогов.
* маска файлов - это набор файлов, заданный с помощью подстановочных знаков * и/или ?
где * - обозначает 0 или больше любых символов в имени файла.
а ? - означает 0 или 1 любой символ в имени файла.
2) Строка
- в двойных кавычках, или без них:
Строкой считается любая последовательность символов, если она не содержит знаков маски * или ?
Смысл цикла здесь в том, чтобы разбить такую строку по пробелам (или знакам табуляции)
и выполнить с каждой подстрокой список команд.
Код:
FOR %%a IN (гитара рыбка) do echo Моя %%a
Если мы хотим, чтобы какая-то из строк не "билась" по пробелам, укажем ее в двойных кавычках:Моя гитара
Моя рыбка
Код:
FOR %%a IN (гитара "дорогая рыбка") do echo Моя %%~a
При этом, чтобы не выводились сами кавычки "" мы используем модификатор* ~ (тильда) при раскрытии переменной цикла %%~aМоя гитара
Моя дорогая рыбка
*О других модификаторах переменной цикла можно почитать здесь и здесь.
3) еще есть смешанный тип. Это когда в наборе стоит маска (1-й описанный тип), а через пробел Строка (2 тип)... ведет себя вполне ожидаемо, но вряд ли найдет себе применение.
О наборах для FOR с ключем /F далее в нижнем спойлере.
Ключ /F часто используется для построчного разбора файла, т.е.
Код:
FOR /f "usebackq delims=" %%a IN ("C:\1.txt") DO echo %%a
UseBackQ (Use back quotes) означает, что набор с двойными кавычками* подразумевает передачу в цикл имени файла.
delims= означает, что в переменную %%a будет записана вся строка (без разделения по пробелу или знаку табуляции, т.к. стандартный разделитель заменен на NULL (пустой символ).
В такой вариации:
tokens=* приводит к тому же результату, что и delims=. Означает прекратить разбивку по разделителю после "0-го" токена, т.е. сразу же.
* Этот вариант необходим для работы с файлом, путь или имя которого содержит пробелы.
Можно было не использовать UseBackQ, тогда команда приняла бы вид:
Код:
FOR /f "tokens=" %%a IN (C:\1.txt) DO echo %%a
** Примеры под спойлером
В цикле FOR /F вид задаваемого набора зависит от формы кавычек в IN (...), а также наличия ключевого слова UseBackQ
Виды наборов для FOR /F:
1) Набор файлов (задание маски недопустимо!)
без UseBackQ - задается без кавычек IN (...)
__с UseBackQ - может задаваться как в кавычках так и без них. IN (...) IN ("...")
2) Строка (допускаются практически любые символы)
без UseBackQ - задается с двойными кавычками IN ("...")
__с UseBackQ - задается с одиночными прямыми кавычками IN ('...')
3) Команда (сначала выполняется она, а уже ее результаты обрабатываются циклом как строка(-и))
без UseBackQ - задается с одиночными прямыми кавычками IN ('...')
__с UseBackQ - задается с одиночными обратными кавычками IN (`...`)
Примеры:
1.1. Чтение файла - Набор файлов
Результат: выведет подряд содержимое двух файлов - 1.txt и 2.txt из каталога c:\users
Прим.: Echo. - с точкой - это обход ошибки, чтобы можно было напечатать пустую строку, точнее строку с пробелами.
1.2. Чтение файла - Набор файлов + UseBackQ
Получаем возможность использовать пробелы.
Результат: выведет содержимое файла 1.txt из каталога c:\folder 1
(заметьте, в имени папки есть пробел).
2.1. Строка
Результат такой же.
3.1. Команда
Сначала выполняется Dir /AD-L, которая выводит информацию о папках в текущем каталоге.
Вот что попадает под разбор циклу:
Далее цикл разбирает каждую строку по пробелам и табуляции на подстроки (токены).
На примере 1-й строки:
1-й токен (%%a)=29.12.2012 ...2-й токен (%%b)=15:16 ...3-й токен (%%c)=<DIR> ...4-й токен (%%d)=Favorites
...
Результат через Echo выводится на экран:
Результат такой же.
Альтернативный вариант нужен с целью, если одна из выполняемых команд требует точно такие же кавычки как и ключевое слово IN (...).
Дабы не пользоваться символом экранирования, просто применяем другие кавычки.
Виды наборов для FOR /F:
1) Набор файлов (задание маски недопустимо!)
без UseBackQ - задается без кавычек IN (...)
__с UseBackQ - может задаваться как в кавычках так и без них. IN (...) IN ("...")
Функционал: чтение содержимого файла(ов) построчно в переменную цикла!
Принцип работы: источником для разбиения по разделителю (delims) является содержимое файла, заданного внутри IN (...) или файлов, если они заданы через пробел.
Исключение: принятый по-умолчанию разделитель (пробел и знак табуляции) для этой конструкции цикла не применяется.
А что получится, если установить delims= (возле равно - знак пробела) ?
В выводе на экран командой Echo %%a мы получим содержимое файла, где каждая из строк будет напечатана до первого встретившегося пробела.
Принцип работы: источником для разбиения по разделителю (delims) является содержимое файла, заданного внутри IN (...) или файлов, если они заданы через пробел.
Исключение: принятый по-умолчанию разделитель (пробел и знак табуляции) для этой конструкции цикла не применяется.
А что получится, если установить delims= (возле равно - знак пробела) ?
Код:
FOR /F "delims= " %%a in (1.txt) do echo %%a
2) Строка (допускаются практически любые символы)
без UseBackQ - задается с двойными кавычками IN ("...")
__с UseBackQ - задается с одиночными прямыми кавычками IN ('...')
3) Команда (сначала выполняется она, а уже ее результаты обрабатываются циклом как строка(-и))
без UseBackQ - задается с одиночными прямыми кавычками IN ('...')
__с UseBackQ - задается с одиночными обратными кавычками IN (`...`)
Примеры:
1.1. Чтение файла - Набор файлов
Код:
FOR /F %%a IN (c:\users\1.txt c:\users\2.txt) do echo.%%a
Прим.: Echo. - с точкой - это обход ошибки, чтобы можно было напечатать пустую строку, точнее строку с пробелами.
1.2. Чтение файла - Набор файлов + UseBackQ
Получаем возможность использовать пробелы.
Код:
FOR /F "usebackq" %%a IN ("c:\folder 1\1.txt") do echo.%%a
(заметьте, в имени папки есть пробел).
2.1. Строка
Код:
FOR /F %%a in ("Каждое слово в отдельную переменную") echo a=%%a; b=%%b; c=%%c; d=%%d; e=%%e
2.2. Строка + UseBackQРезультат написал(а):a=Каждое; b=слово; c=в; d=отдельную; e=переменную
Код:
FOR /F "UseBackQ" %%a in ('Каждое слово в отдельную переменную') echo a=%%a; b=%%b; c=%%c; d=%%d; e=%%e
3.1. Команда
Код:
For /F "tokens=1-4" %%a IN ('Dir /A:D-L') Do Echo Папка %%d Дата модификации %%a. Время %%b
Вот что попадает под разбор циклу:
Далее цикл разбирает каждую строку по пробелам и табуляции на подстроки (токены).
На примере 1-й строки:
1-й токен (%%a)=29.12.2012 ...2-й токен (%%b)=15:16 ...3-й токен (%%c)=<DIR> ...4-й токен (%%d)=Favorites
...
Результат через Echo выводится на экран:
3.2. Команда + UseBackQПапка Favorites Дата модификации 29.12.2012. Время 15:16
Папка Links Дата модификации 14.01.2013. Время 01:51
...и т.д.
Код:
For /F "Usebackq tokens=1-4" %%a IN (`Dir /A:D-L`) Do Echo Папка %%d Дата модификации %%a. Время %%b
Альтернативный вариант нужен с целью, если одна из выполняемых команд требует точно такие же кавычки как и ключевое слово IN (...).
Дабы не пользоваться символом экранирования, просто применяем другие кавычки.
Отличительной особенностью FOR /F является умение работать через токены*,
а также поддержка дополнительных ключевых слов:
1) eol - знак комментария в начале строки (1-й символ). Т.е. строки с таким символом не будут обрабатываться. (по умолчанию, знак точки с запятой ; )
2) skip - пропуск определенного кол-ва обрабатываемых строк от начала файла
3) delims - задать другой разделитель(-ли) (по умолчанию, пробел и знак табуляции)
4) tokens - количество получаемых токенов (подстрок) в теле цикла и пределы разбивки по разделителю.
Также можно задать конкретный № токена, который попадет в первую переменную цикла.
5) usebackq - изменение правил использования кавычек внутри IN (...)
Детальную справку можно получить, введя в консоль команду FOR /?
* Токены - это подстроки, которые попадают в переменные цикла %% в каждой из итераций.
Они получаются в результате разбивки строки, заданной в IN (...), по разделителю, заданному в Delims= (по умолчанию, пробел и знак табуляции).
В отличие, от FOR без ключа, в FOR /F все токены (все подстроки одной строки) попадают сразу В ПЕРВУЮ ИТЕРАЦИЮ цикла.
Они будут распределены по РАЗНЫМ переменным цикла, идущим в алфавитном порядке*, начиная с буквы, заданной после FOR /F %%
Т.е.
Код:
FOR /F %%a IN ("гитара рыбка") do echo Моя %%a и моя %%b.
*Моя гитара и моя рыбка.
Максимальное кол-во токенов составляет - 26,
если начальным указать %%a либо %%A (регистр имеет значение)
При этом переход с %%z в %%A не происходит. Остальная часть подстрок опускается.
Можно проверить:
Бывают случаи, когда требуется разбить строку по специфическому разделителю и при этом выполнить одну и ту же команду над каждой из подстрок (токеном). Кол-во токенов неизвестно.
Метод показал Anonymоus в теме Символ переноса строки в переменной окружения
Алгоритм заключается в замене разделителя на пробел с одновременным заключением каждого токена в двойные кавычки. Далее строка разбирается обычным циклом FOR без ключа.
если начальным указать %%a либо %%A (регистр имеет значение)
При этом переход с %%z в %%A не происходит. Остальная часть подстрок опускается.
Можно проверить:
Код:
For /F "tokens=1,2" %%z IN ("1 2") do echo %%A
Метод показал Anonymоus в теме Символ переноса строки в переменной окружения
Алгоритм заключается в замене разделителя на пробел с одновременным заключением каждого токена в двойные кавычки. Далее строка разбирается обычным циклом FOR без ключа.
Более универсальные конструкции на основе FOR /F для работы с файлами/папками строятся путем помещения
в IN ('...') команды, результаты от выполнения которой уж затем обрабатываются циклом.
Чаще всего это команда Dir.
1.2. Чтение файла (сложный пример).
Давайте возьмем сложный пример, и раскусим "крепкий орешек"
Имеем в распоряжении файл 1.txt, который находится рядом с батником.
1) %~dp0 - означает каталог, где находится батник, например c:\temp\
2) UseBackQ, ага - значит если в IN (...) ничего нет или двойные кавычки, то это файл и его нужно прочесть.
3) Читаем содержимое файла 1.txt в папке %~dp0, а затем каждую его строку проверяем по правилам... ключевых слов skip=1 tokens=2 delims=/\ eol=
4) Итак, первая строка так и называется "первая строка"
skip=1 - означает пропустить от начала файла 1-у строку,
значит идем дальше:
5) Вторая строка: ";комментарий/кода"
Первый символ - это точка с запятой. А теперь смотрим сюда "eol=пустой символ".
По умолчанию eol=; и если бы мы не указали пустой EOL, то цикл просто бы пропустил эту строку.
Итак, символ комментария не совпадает с заданным (т.е. он вообще пустой), а значит строчка нам подходит -> проверяем ее дальше:
6) Смотрим какие приняты разделители: delims=/\ (знаки / и \ ), значит
из строки ";комментарий/кода"
мы получим 2 подстроки:
1-й токен - ";комментарий"
2-й токен - "кода"
7) Теперь смотрим сюда tokens=2 - значит, что первой букве цикла нужно присвоить значение 2-го токена.
Первая буква цикла у нас X. Переменная называется %%X
А второй токен - это подстрока "кода"
8) Только теперь мы попадаем в тело цикла: Echo %%X
что означает - вывести на экран текст "кода"
С 3-ей строкой потренируйтесь самостоятельно.
Давайте возьмем сложный пример, и раскусим "крепкий орешек"

Код:
FOR /F "UseBackQ skip=1 tokens=2 delims=/\ eol=" %%X in ("%~dp01.txt") do echo %%X
Порядок разбора (или "как прибл. будет думать ком. строка"):Содержимое файла 1.txt написал(а):первая строка
;комментарий/кода
наше любимое\блюдо
1) %~dp0 - означает каталог, где находится батник, например c:\temp\
2) UseBackQ, ага - значит если в IN (...) ничего нет или двойные кавычки, то это файл и его нужно прочесть.
3) Читаем содержимое файла 1.txt в папке %~dp0, а затем каждую его строку проверяем по правилам... ключевых слов skip=1 tokens=2 delims=/\ eol=
4) Итак, первая строка так и называется "первая строка"

skip=1 - означает пропустить от начала файла 1-у строку,
значит идем дальше:
5) Вторая строка: ";комментарий/кода"
Первый символ - это точка с запятой. А теперь смотрим сюда "eol=пустой символ".
По умолчанию eol=; и если бы мы не указали пустой EOL, то цикл просто бы пропустил эту строку.
Итак, символ комментария не совпадает с заданным (т.е. он вообще пустой), а значит строчка нам подходит -> проверяем ее дальше:
6) Смотрим какие приняты разделители: delims=/\ (знаки / и \ ), значит
из строки ";комментарий/кода"
мы получим 2 подстроки:
1-й токен - ";комментарий"
2-й токен - "кода"
7) Теперь смотрим сюда tokens=2 - значит, что первой букве цикла нужно присвоить значение 2-го токена.
Первая буква цикла у нас X. Переменная называется %%X
А второй токен - это подстрока "кода"
8) Только теперь мы попадаем в тело цикла: Echo %%X
что означает - вывести на экран текст "кода"
С 3-ей строкой потренируйтесь самостоятельно.
кода
блюдо
блюдо
Ключ /L
Код:
FOR /L %%a IN (0,2,6) DO echo %%a
означает математическое перечисление чисел от первого числа (0), до третьего (6), с шагом, указанным вторым числом (2) в наборе IN (...).
Указанная команда выведет:
Прим.: дробные числа командной строкой не поддерживаются.0
2
4
6