You have to additionally use the tokens=1,2,...
part of the options that the for
loop allows. This here will do what you possibly want:
for /f "tokens=1,2,3,4,5,6,7,8,9,10,11,12 delims=;" %a in ("%PATH%") ^
do ( ^
echo. %b ^
& echo. %a ^
& echo. %c ^
& echo. %d ^
& echo. %e ^
& echo. %f ^
& echo. %g ^
& echo. %h ^
& echo. %i ^
& echo. %j ^
& echo. %k ^
& echo. ^
& echo. ...and now for some more... ^
& echo. ^
& echo. %a ^| %b ___ %c ... %d ^
& dir "%e" ^
& cd "%f" ^
& dir /tw "%g" ^
& echo. "%h %i %j %k" ^
& cacls "%f")
This example processes the first 12 tokens (=directories from %path%) only. It uses explicit enumeration of each of the used tokens. Note, that the token names are case sensitive: %a is different from %A.
To be save for paths with spaces, surround all %x with quotes like this «%i». I didn’t do it here where I’m only echoing the tokens.
You could also do s.th. like this:
for /f "tokens=1,3,5,7-26* delims=;" %a in ("%PATH%") ^
do ( ^
echo. %c ^
& echo. %b ^
& echo. %a ^
& echo. %d ^
& echo. %e ^
& echo. %f ^
& echo. %g ^
& echo. %h ^
& echo. %i ^
& echo. %j ^
& echo. %k )
This one skips tokens 2,4,6 and uses a little shortcut («7-26
«) to name the rest of them. Note how %c, %b, %a are processed in reverse order this time, and how they now ‘mean’ different tokens, compared to the first example.
So this surely isn’t the concise explanation you asked for. But maybe the examples help to clarify a little better now…
В этой статье мы рассмотрим, как использовать конструкцию for в командной строке для перебора значений и файлов. Все примеры в статье я буду приводить с учетом, что код будет выполнятся в теле сценария, который, в свою очередь будет запускаться из консоли командной строки.
Лично я, сперва добавляю в переменную окружения PATH путь к каталогу, в котором находится сценарий:
set%PATH%;путь_к _каталогу
После этого я просто ввожу в консольном окне имя сценария, например, test.bat. Помните, что путь будет храниться в переменной окружения лишь в пределах текущего окна командной строки.
Командная строка for – перебор значений
Для перебора значений используется следующий синтаксис:
for /L %%переменная in (начало, шаг, конец) do (оператор)
Ключ /L говорит о том, что происходит перебор данных, далее следует имя переменной, в которую эти данные будут записываться. В круглых скобках нужно через запятую указать три параметра:
- начало – начальное значение
- шаг – тут мы указывает, насколько нужно увеличивать или уменьшать начальное значение при каждой итерации. То есть, если параметр содержит отрицательное число, то будет происходить уменьшение, иначе – увеличение параметра “начало”.
- конец – тут нужно указать конечное значение, именно оно и будет определять, завершать цикл или нет. То есть, при каждой итерации происходит сравнивание начального и конечного параметра.
Давайте рассмотрим такой пример:
@echo offfor/L %%B in(0,1,5)doecho%%Becho.for/L %%B in(5,-1,0)doecho%%B
В данном сценарии используются два цикла for командной строки, первый задает диапазон цифр от 0 до 5 с шагом 1, второй – диапазон цифр от 5 до 0 с шагом -1. То есть, прямой и обратный порядок. Функция ЭХО будет в виде списка выводить содержимое переменной B. Команда “echo.” вставляем между списками пустую строку.
Теперь попробуем найти сумму чисел от 0 до 100:
@echo offsetsumm=0for/L %%B in(0,1,100)do set/A summ+=%%Becho%summ%setsumm=
Сначала мы отключаем вывод эхо-отображений. Потом мы объявляем переменную summ с помощью ключевого слова set и присваиваем ей ноль. Далее в цикле for задаем начальное значение в 0, шаг в 1 и конечное значение в 100. Суммирование происходит в строке set/A summ+=%%B, тут к содержимому переменной summ будет добавляться содержимое переменной %%B. В конце мы выводим конечный результат и удаляем из окружения summ.
Теперь давайте посмотрим, как будет выглядеть код для нахождения факториала числа 5:
@echo offsetfact=1for/L %%B in(5,-1,1)do set/A fact*=%%Becho%fact%setfact=
Тут практически тот же самый синтаксис, за исключением того, что мы задали отрицательный шаг и использовали оператор *=.
Хорошо, теперь усложним задачу: найдем сумму чисел от 0 до 10, исключив из расчета числа 5, 7 и 9:
@echo offsetsumm=0for/L %%B in(0,1,10)do(if"%%B" neq "5"(if"%%B" neq "7"(if"%%B" neq "9" set/A summ+=%%B)))echo%summ%setsumm=
Как видим, для проверки условия мы использовали условный оператор if. К сожалению, в командной строке нет логических операторов тип “ИЛИ” и “И”, как например, в языках vbscript и jscript, поэтому нам пришлось создавать вложенные операторы if. В результате, мы получили число 34. Также обратите внимание на оператор “neq” – проверка условия типа “НЕ РАВНО”.
Командная строка for – работа с файлами
Для групповой работы с файлами используется следующий синтаксис цикла for командной строки:
for %переменная in (набор_файлов) do (оператор)
Базовый параметр тут переменная набор_файлов, которая может содержать:
- отдельный файл, например, my_file.txt
- групповой набор документов, заданный через шаблон, например, *.txt
- список файлов, который разделяется пробелами, причем каждый элемент списка тоже может содержать шаблон, например, my_file.txt *.doc my*.avi
Стоит учитывать тот факт, что если не указывать путь к файлу, то поиск будет производиться в текущем каталоге – в том каталоге, из которого производится запуск сценария.
В следующем примере происходит вывод всех файлов из каталога d:work с расширением .txt:
@echo offfor%%В in(d:work*.txt)do(echo%%В)
Тут B является переменной инициализации, при каждой итерации ей будет присвоено путь, имя и расширение найденного текстового документа, а функция ЭХО сразу выведет информацию на экран. Потом снова, переменной B будет присвоено новое имя и снова произойдет вывод данных. Сам цикл работает до тех пор, пока не будут найдены все значения, заданные в условии.
Естественно, можно задать условие для вывода всех файлов с расширениями, например, .txt, .avi и .pdf.
@echo offsetwork_dir=d:workfor%%B in(%work_dir%*.txt %work_dir%*.avi %work_dir%*.pdf)do(echo%%B)setwork_dir=
В данном случае переменная work_dir содержит путь к папке d:work, в цикле командной строки for мы добавляем к переменной нужные расширения. В конце сценария происходит удаление переменной work_dir.
Также стоит понимать, что вместо одного оператора (в данном случае эхо) можно прописать несколько, сгруппировав их символом &. То есть, данный цикл позволяет в групповом порядке обработать одним махом несколько файлов. Только не забывайте, что при формировании группы их стоит заключить в круглые скобки. Например:
Можно попробовать получить список имен файлов и их размер:
@echo offfor%%B in(%SystemRoot%*.txt)do(echo%%B %%~zB)
Конструкция ~z позволяет получить размер файла в байтах.
Что бы использовать сразу цикл в командной строке, стоит вместо двух символов % прописывать один, например:
for%B in(%SystemRoot%*.txt)do(echo%B %%~zB)
Запуск некоторой команды для каждого файла из заданного множества.
Синтаксис
for {%переменная|%%переменная} in (множество) do команда [ПараметрыКоманднойСтроки]
Параметры
- {%переменная|%%переменная}
- Обязательный параметр. Замещаемый параметр. Используйте %переменнаядля выполнения команды for из командной строки. Используйте%%переменная для выполнения команды for в пакетном файле. Переменные учитывают регистр и могут быть представлены со значением альфа, например, %A, %B или %C.
- (множество)
- Обязательный параметр. Задает один или несколько файлов, каталогов, диапазон значений или текстовых строк, подлежащих обработке заданной командой. Скобки являются обязательными.
- команда
- Обязательный параметр. Задает команду, которая будет выполнена для каждого файла, каталога диапазона значений или текстовой строки, включенной в указанный параметр (множество).
- ПараметрыКоманднойСтроки
- Задает параметры командной строки, которые используются с указанной командой.
- /?
- Отображение справки в командной строке.
Заметки
- Использование программы for
Команда for может быть использована в пакетном файле или непосредственно из командной строки.
- Использование параметров командной строки пакетного файла
Перечисленные ниже атрибуты применяются к команде for.
- В команде for переменная %%переменная (или %%переменная) будет заменяться текстовой строкой из заданного параметра множество, пока параметр команда не обработает все файлы этого множества.
- Имена параметров переменная команды for учитывают регистр буквы, они являются глобальными и одновременно может быть активно не больше 52 переменных.
- Для обозначения параметра переменная можно использовать любые символы, кроме цифр 09, чтобы не было конфликта с параметрами пакетных файлов %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 [«КлючевыеСловаРазбора«] {%% | %}переменная in (МножествоИменФайлов) 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прекращает %~ syntax.
Использование прописных букв в именах переменных, например %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 на %%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
В данном примере перечисляются имена переменных среды в текущем окружении.
04.02.2013, 00:56. Показов 289679. Ответов 16
Вдохновившись сообщением от FraidZZ, написал мини-статейку, основанную на изложенных им положениях.
Заметки
Циклическиe операции FOR
Командой FOR задаётся список команд, которые выполняются с КАЖДЫМ элементом набора.
Набор* пишется внутри IN (…)
Список команд пишется внутри DO (…)
Командная строка выполняет эти команды раз за разом, при этом текущий элемент набора находится в переменной, заданной после %% (назовём ее переменной цикла).
Например,
Windows Batch file | ||
|
выведет имена и путь ко всем файлам с расширением .txt в папке C:Users.
* Примеры под спойлером
Виды наборов для FOR
Для команды For без ключей набором может являться:
1) Маска файлов* (или путь + маска файлов)
— в двойных кавычках, или без них:
IN (*.txt)
Результат: список файлов с расширением .txt в текущем каталоге.
IN (*.txt *.bat)
Результат: список файлов с расширениеми .txt и .bat в текущем каталоге.
IN («C:Folder 1Doc_31-12-*.txt»)
Результат: тот же. Но поиск ведется в каталоге C:Folder 1 (заметьте с пробелом в имени);
имя файла начинается на Doc_31-12-
Прим.: FOR без ключа не умеет выводить список каталогов.
* маска файлов — это набор файлов, заданный с помощью подстановочных знаков * и/или ?
где * — обозначает 0 или больше любых символов в имени файла.
а ? — означает 0 или 1 любой символ в имени файла.
2) Строка
— в двойных кавычках, или без них:
Строкой считается любая последовательность символов, если она не содержит знаков маски * или ?
Смысл цикла здесь в том, чтобы разбить такую строку по пробелам (или знакам табуляции)
и выполнить с каждой подстрокой список команд.
Windows Batch file | ||
|
Результат:
Если мы хотим, чтобы какая-то из строк не «билась» по пробелам, укажем ее в двойных кавычках:
Windows Batch file | ||
|
Результат:
Моя гитара
Моя дорогая рыбка
При этом, чтобы не выводились сами кавычки «» мы используем модификатор* ~ (тильда) при раскрытии переменной цикла %%~a
*О других модификаторах переменной цикла можно почитать здесь и здесь.
Не по теме:
3) еще есть смешанный тип. Это когда в наборе стоит маска (1-й описанный тип), а через пробел Строка (2 тип)… ведет себя вполне ожидаемо, но вряд ли найдет себе применение.
О наборах для FOR с ключем /F далее в нижнем спойлере.
Ключ /F часто используется для построчного разбора файла, т.е.
Windows Batch file | ||
|
выведет все строки файла 1.txt, который находится в корне диска C.
UseBackQ (Use back quotes) означает, что набор с двойными кавычками* подразумевает передачу в цикл имени файла.
delims= означает, что в переменную %%a будет записана вся строка (без разделения по пробелу или знаку табуляции, т.к. стандартный разделитель заменен на NULL (пустой символ).
В такой вариации:
tokens=* приводит к тому же результату, что и delims=. Означает прекратить разбивку по разделителю после «0-го» токена, т.е. сразу же.
* Этот вариант необходим для работы с файлом, путь или имя которого содержит пробелы.
Можно было не использовать UseBackQ, тогда команда приняла бы вид:
Windows Batch file | ||
|
но такая конструкция восприняла бы пробел в имени как определение нового файла, поэтому UseBackQ более приемлем.
** Примеры под спойлером
Виды наборов для FOR /F
В цикле FOR /F вид задаваемого набора зависит от формы кавычек в IN (…), а также наличия ключевого слова UseBackQ
Виды наборов для FOR /F:
1) Набор файлов (задание маски недопустимо!)
без UseBackQ — задается без кавычек IN (…)
__с UseBackQ — может задаваться как в кавычках так и без них. IN (…) IN («…»)
Специфика работы
Функционал:
чтение содержимого файла(ов) построчно в переменную цикла!
Принцип работы:
источником для разбиения по разделителю (delims) является содержимое файла, заданного внутри IN (…) или файлов, если они заданы через пробел.
Исключение:
принятый по-умолчанию разделитель (пробел и знак табуляции) для этой конструкции цикла не применяется.
А что получится, если установить delims= (возле равно — знак пробела) ?
Windows Batch file | ||
|
В выводе на экран командой Echo %%a мы получим содержимое файла, где каждая из строк будет напечатана до первого встретившегося пробела.
.
2) Строка (допускаются практически любые символы)
без UseBackQ — задается с двойными кавычками IN («…»)
__с UseBackQ — задается с одиночными прямыми кавычками IN (‘…’)
3) Команда (сначала выполняется она, а уже ее результаты обрабатываются циклом как строка(-и))
без UseBackQ — задается с одиночными прямыми кавычками IN (‘…’)
__с UseBackQ — задается с одиночными обратными кавычками IN (`…`)
Примеры:
1.1. Чтение файла — Набор файлов
Windows Batch file | ||
|
Результат: выведет подряд содержимое двух файлов — 1.txt и 2.txt из каталога c:users
Прим.: Echo. — с точкой — это обход ошибки, чтобы можно было напечатать пустую строку, точнее строку с пробелами.
1.2. Чтение файла — Набор файлов + UseBackQ
Получаем возможность использовать пробелы.
Windows Batch file | ||
|
Результат: выведет содержимое файла 1.txt из каталога c:folder 1
(заметьте, в имени папки есть пробел).
2.1. Строка
Windows Batch file | ||
|
Сообщение от Результат
a=Каждое; b=слово; c=в; d=отдельную; e=переменную
2.2. Строка + UseBackQ
Windows Batch file | ||
|
Результат такой же.
3.1. Команда
Windows Batch file | ||
|
Сначала выполняется Dir /AD-L, которая выводит информацию о папках в текущем каталоге.
Вот что попадает под разбор циклу:
Далее цикл разбирает каждую строку по пробелам и табуляции на подстроки (токены).
На примере 1-й строки:
1-й токен (%%a)=29.12.2012 …2-й токен (%%b)=15:16 …3-й токен (%%c)=<DIR> …4-й токен (%%d)=Favorites
…
Результат через Echo выводится на экран:
Папка Favorites Дата модификации 29.12.2012. Время 15:16
Папка Links Дата модификации 14.01.2013. Время 01:51
…и т.д.
3.2. Команда + UseBackQ
Windows Batch file | ||
|
Результат такой же.
Альтернативный вариант нужен с целью, если одна из выполняемых команд требует точно такие же кавычки как и ключевое слово IN (…).
Дабы не пользоваться символом экранирования, просто применяем другие кавычки.
Отличительной особенностью FOR /F является умение работать через токены*,
а также поддержка дополнительных ключевых слов:
1) eol — знак комментария в начале строки (1-й символ). Т.е. строки с таким символом не будут обрабатываться. (по умолчанию, знак точки с запятой ; )
2) skip — пропуск определенного кол-ва обрабатываемых строк от начала файла
3) delims — задать другой разделитель(-ли) (по умолчанию, пробел и знак табуляции)
4) tokens — количество получаемых токенов (подстрок) в теле цикла и пределы разбивки по разделителю.
Также можно задать конкретный № токена, который попадет в первую переменную цикла.
5) usebackq — изменение правил использования кавычек внутри IN (…)
Детальную справку можно получить, введя в консоль команду FOR /?
* Токены — это подстроки, которые попадают в переменные цикла %% в каждой из итераций.
Они получаются в результате разбивки строки, заданной в IN (…), по разделителю, заданному в Delims= (по умолчанию, пробел и знак табуляции).
В отличие, от FOR без ключа, в FOR /F все токены (все подстроки одной строки) попадают сразу В ПЕРВУЮ ИТЕРАЦИЮ цикла.
Они будут распределены по РАЗНЫМ переменным цикла, идущим в алфавитном порядке*, начиная с буквы, заданной после FOR /F %%
Т.е.
Windows Batch file | ||
|
Результат:
Обратите внимание: по умолчанию, цикл выдаёт в результатах только 1-ый токен. Если вам нужно, получить другой, нужно явно указывать модификатор «tokens=xxx».
*
Макс. количество токенов и обход ограничения
Максимальное кол-во токенов составляет — 26,
если начальным указать %%a либо %%A (регистр имеет значение)
При этом переход с %%z в %%A не происходит. Остальная часть подстрок опускается.
Можно проверить:
Windows Batch file
For /F "tokens=1,2" %%z IN ("1 2") do echo %%A
Бывают случаи, когда требуется разбить строку по специфическому разделителю и при этом выполнить одну и ту же команду над каждой из подстрок (токеном). Кол-во токенов неизвестно.
Метод показал Anonymоus в теме Символ переноса строки в переменной окружения
Алгоритм заключается в замене разделителя на пробел с одновременным заключением каждого токена в двойные кавычки. Далее строка разбирается обычным циклом FOR без ключа.
Более универсальные конструкции на основе FOR /F для работы с файлами/папками строятся путем помещения
в IN (‘…’) команды, результаты от выполнения которой уж затем обрабатываются циклом.
Чаще всего это команда Dir.
А теперь рассмотрим более сложный пример:
1.2. Чтение файла (сложный пример).
Давайте возьмем сложный пример, и раскусим «крепкий орешек»
Windows Batch file | ||
|
Имеем в распоряжении файл 1.txt, который находится рядом с батником.
Сообщение от Содержимое файла 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
А второй токен — это подстрока «кода»
Только теперь мы попадаем в тело цикла: Echo %%X
что означает — вывести на экран текст «кода»
С 3-ей строкой потренируйтесь самостоятельно.
Вот такой результат окажется на экране:
Ключ /L
Windows Batch file | ||
|
IN (первое, шаг, последнее)
означает математическое перечисление чисел от первого числа (0), до третьего (6), с шагом, указанным вторым числом (2) в наборе IN (…).
Указанная команда выведет:
Прим.: дробные числа командной строкой не поддерживаются.
Миниатюры
16
for
— команда, организовывающая цикл в командной строке (CMD) Windows. Аналог цикла for
в C-подобн. ЯП.
Содержание
- 1 Преамбула
- 2 Синтаксис
- 3 Переменные
- 3.1 Особенности переменных
- 4 Расширенная обработка команд
- 5 Числовой цикл
- 5.1 Пример числового цикла
- 6 Бесконечный цикл
- 6.1 Примеры бесконечного цикла
- 7 Перебор всех файлов в директории
- 8 Документация
- 9 Также
- 10 Ссылки
Преамбула
Цикл for
производит выполнение указанной команды для каждого файла набора.
Синтаксис
FOR %переменная IN (набор) DO команда [параметры]
Где:
-
%переменная
– Однобуквенный подставляемый параметр. - (набор) – Определяет набор, состоящий из одного или нескольких файлов. Допускается использ. подстановочных знаков.
- команда – Команда, которую следует выполнить для каждого файла.
- параметры – Параметры и ключи для указанной команды.
Переменные
В пакетных файлах для команды for
используется запись %%переменная
, вместо %переменная
, т.е. в файлах переменные начинаются с 2-ух знаков
%
, а в командной строке – с одного.
Особенности переменных
- Имена переменных учитывают регистр букв — напр.,
%i
отличается от%I
. - Переменные должны быть односимвольными, по крайней мере для числового цикла.
Расширенная обработка команд
Если включена расширенная обработка команд, поддерживаются след. доп. формы команды for
:
FOR /D %переменная IN (набор) DO команда [параметры]
Если набор содержит подстановочные знаки, команда выполняется для всех подходящих имен каталогов, а не имён файлов.
Числовой цикл
Для организации самого распространённого числового цикла, т.е., цикла, перебирающего числа, для команды for
нужно использ. параметр /L
.
Синтаксис числового цикла:
FOR /L %%parameter IN (start,step,end) DO command
Пример числового цикла
FOR /L %p IN (1,1,10) DO echo %p
Это числовой цикл от 1 до 10 с шагом приращения 1. На каждой итерации цикла с помощью команды echo
выводится переменная шага цикла — счётчика.
Бесконечный цикл
Бесконечный цикл можно реализовать на базе числового без задания настроек счётчика, тогда цикл будет бесконечным.
Примеры бесконечного цикла
Пример бесконечного цикла 1:
for /l %x in (0,0,0) do echo «бесконечный цикл»
Пример бесконечного цикла 2:
for /l %x in (0,0,0) do curl http://domain.local-domain-zone/path/script.php
Перебор всех файлов в директории
for %i in (*) do echo %i
рекурсивно:
for /r %i in (*) do echo %i
Отображать только имена файлов (не полный путь) с их расширениями в текущем каталоге:
for %i in (*) do ( echo %~nxi )
рекурсивно:
for /r %i in (*) do ( echo %~nxi )
files in current dir:
for %f in (.*) do @echo %f
subdirs in current dir:
for /D %s in (.*) do @echo %s
files in current and all subdirs:
for /R %f in (.*) do @echo %f
subdirs in current and all subdirs:
for /R /D %s in (.*) do @echo %s
Документация
Если набор содержит подстановочные знаки, команда выполняется для всех подходящих имен каталогов, а не имен файлов.
FOR /R [[диск:]путь] %переменная IN (набор) DO команда [параметры]
Выполнение команды для каталога [диск:]путь, а также для всех подкаталогов этого пути. Если после ключа /R не указано имя каталога, используется текущий каталог. Если набор — это одиночный символ точки (.), команда просто перечисляет дерево каталогов.
FOR /L %переменная IN (начало,шаг,конец) DO команда [параметры]
Набор раскрывается в последовательность чисел с заданными началом, концом и шагом приращения. Так, набор (1,1,5) раскрывается в (1 2 3 4 5), а набор (5,-1,1) — в (5 4 3 2 1)
FOR /F ["ключи"] %переменная IN (набор-файлов) DO команда [параметры] FOR /F ["ключи"] %переменная IN ("строка") DO команда [параметры] FOR /F ["ключи"] %переменная IN ('команда') DO команда [параметры]
или, если использован параметр usebackq:
FOR /F ["ключи"] %переменная IN (набор-файлов) DO команда [параметры] FOR /F ["ключи"] %переменная IN ('строка') DO команда [параметры] FOR /F ["ключи"] %переменная IN (`команда`) DO команда [параметры]
Набор файлов содержит имена одного или нескольких файлов, которые по очереди открываются, читаются и обрабатываются. Обработка состоит в чтении файла, разбивке его на отдельные строки текста и разборе каждой строки в ноль или более подстрок. Затем вызывается тело цикла for
, при выполнении которого каждая найденная подстрока используется в качестве значения переменной. По умолчанию ключ /F выделяет из каждой строки каждого файла первую отделенную пробелами подстроку. Пустые строки в файле пропускаются. Необязательный параметр «ключи» служит для переопределения правил разбора по умолчанию. Он представляет собой заключенную в кавычки строку, содержащую одно или несколько ключевых слов для определения параметров разбора. Ключевые слова:
- eol=c — знак начала комментария в конце строки (допускается задание только одного знака).
- skip=n — число пропускаемых при обработке строк в начале файла.
- delims=xxx — набор разделителей вместо используемых по умолчанию пробела и знака табуляции.
- tokens=x,y,m-n — номера подстрок из каждой строки, передаваемые в тело цикла
for
для каждой итерации. При использовании этого ключа выделяются дополнительные имена переменных. Формат m-n представляет собой диапазон подстрок с номерами от m по n. Если последний знак в строке tokens= является звездочкой, создается дополнительная переменная, значением которой будет весь оставшийся текст в строке после разбора последней подстроки. - usebackq — применение новой семантики, при которой строка, заключенная в обратные кавычки, выполняется как команда, строка, заключенная в прямые одиночные кавычки, является строкой-литералом, а двойные кавычки могут использоваться для задания имен файлов в наборе.
Поясняющий пример:
FOR /F "eol=; tokens=2,3* delims=, " %i in (мойфайл.txt) do @echo %i %j %k
разбирает файл myfile.txt, пропуская все строки, которые начинаются с символа точки с запятой, и передает вторую и третью подстроки из каждой строки в тело цикла for
, причем подстроки разделяются запятыми и/или пробелами. В теле цикла переменная %i используется для второй подстроки, %j — для третьей, а %k получает все оставшиеся подстроки после третьей. Имена файлов, содержащие пробелы, необходимо заключать в двойные кавычки. Чтобы использовать двойные кавычки, необходимо использовать параметр usebackq, иначе двойные кавычки будут восприняты как определение строки-литерала для разбора.
Переменная %i явно объявлена в инструкции for
, а переменные %j и %k объявляются неявно с помощью ключа tokens=. Ключ tokens= позволяет извлечь из одной строки файла до 26 подстрок, при условии, что это не приведет к попытке объявить переменную после буквы «z» или «Z». Следует помнить, что имена переменных for
явл. однобуквенными, с учетом регистра, глобальными, поэтому одновременно не может быть активно более 52 переменных.
Логику разбора команды FOR /F можно также использовать на явно заданной строке, заключив ее в одиночные кавычки и указав ее в качестве параметра в скобках. Она будет разобрана как одиночная строка из входного файла.
Наконец, команда FOR /F позволяет разобрать выходные данные другой команды. Для этого следует использовать в качестве параметра в скобках строку в обратных одиночных кавычках. Эта строка передается для выполнения дочернему обработчику команд CMD.EXE, а вывод этой команды сохраняется в памяти и разбирается так, как если бы это был файл. Следующий пример,
FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i,
выведет перечень имен всех переменных среды в текущей среде.
Операции подстановки ссылок на переменные команды for
также расширены. Допускается применение след. синтаксич. конструкций:
- %~I — из переменной %I удаляются обрамляющие кавычки («)
- %~fI — переменная %I расширяется до полного имени файла
- %~dI — из переменной %I выделяется только имя диска
- %~pI — из переменной %I выделяется только путь к файлу
- %~nI — из переменной %I выделяется только имя файла
- %~xI — из переменной %I выделяется расширение имени файла
- %~sI — полученный путь содержит только короткие имена
- %~aI — переменная %I расширяется до атрибутов файла
- %~tI — переменная %I расширяется до даты /времени файла
- %~zI — переменная %I расширяется до размера файла
- %~$ПУТЬ:I — проводится поиск по каталогам, заданным в переменной среды ПУТЬ, и переменная %I заменяется на полное имя первого найденного файла. Если переменная ПУТЬ не определена или в результате поиска не найден ни один файл, то этот модификатор заменяется на пустую строку.
При объединении нескольких операторов можно получить следующие результаты:
- ~dpI — переменная I раскрывается в имя диска и путь
- ~nxI — переменная I раскрывается в имя файла и его расширение
- ~fsI — переменная I раскрывается в полный путь с короткими именами
- ~dp$ПУТЬ:I — проводится поиск по каталогам, заданным в переменной среды ПУТЬ, и переменная I раскрывается в имя диска и путь к первому найденному файлу.
- ~ftzaI — переменная I раскрывается в строку, подобную выдаваемой командой DIR
В приведенных выше примерах переменные I и ПУТЬ можно заменить на другие допустимые значения. Синтаксическая конструкция с символами ~ заканчивается допустимым именем переменной цикла for
.
Для имен переменных рекомендуется использовать заглавные буквы, например, I, что делает эту конструкцию более удобной для чтения и предотвращает ошибочное принятие их за модификаторы, которые не различают регистр.
Также
FOR Conditionally perform a command several times. 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 The operation of the FOR command can be summarised as... Take a set of data Make a FOR Parameter %%G equal to some part of that data Perform a command (optionally using the parameter as part of the command). Repeat for each item of data If you are using the FOR command at the command line rather than in a batch program, use just one percent sign: %G instead of %%G. FOR Parameters The first parameter has to be defined using a single character, for example the letter G. FOR %%G IN ... In each iteration of a FOR loop, the IN ( ....) clause is evaluated and %%G set to a different value If this clause results in a single value then %%G is set equal to that value and the command is performed. If the clause results in a multiple values then extra parameters are implicitly defined to hold each. These are automatically assigned in alphabetical order %%H %%I %%J ...(implicit parameter definition) If the parameter refers to a file, then enhanced variable reference can be used to extract the filename/path/date/size. You can of course pick any letter of the alphabet other than %%G. %%G is a good choice because it does not conflict with any of the pathname format letters (a, d, f, n, p, s, t, x) and provides the longest run of non-conflicting letters for use as implicit parameters. G > H > I > J > K > L > M Format letters are case sensitive, so using a capital letter is also a good way to avoid conflicts %%A rather than %%a. Examples FOR /F "tokens=1-5" %%A IN ("This is a short sentence") DO @echo %%A %%B %%D will result in the output: This is short Create a set of 26 folders, one for each letter of the alphabet: FOR %%G IN (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) DO (md C:demo%%G) Running multiple commands in a FOR loop Within a FOR loop, variables are expanded at the start of the loop and don’t update until the entire DO section has completed. The following example counts the files in the current folder, but %count% always returns 1: @echo off SET count=1 FOR /f "tokens=*" %%G IN ('dir /b') DO ( echo %count%:%%G set /a count+=1 ) To update variables within each iteration of the loop we must either use EnableDelayedExpansion or else use the CALL :subroutine mechanism as shown below: @echo off SET count=1 FOR /f "tokens=*" %%G IN ('dir /b') DO (call :subroutine "%%G") GOTO :eof :subroutine echo %count%:%1 set /a count+=1 GOTO :eof Nested FOR commands FOR commands can be nested FOR %%G... DO (for %%U... do ...) when nesting commands choose a different letter for each part. you can then refer to both parameters in the final DO command. For an example of exiting the inner loop of two nested FOR loops, see the EXIT page. If Command Extensions are disabled, the FOR command will only support the basic syntax with no enhanced variables: FOR %%parameter IN (set) DO command [command-parameters] FOR is an internal command. “Those who cannot remember the past are condemned to repeat it” - George Santayana Related: FOR - Loop through a set of files in one folder FOR /R - Loop through files (recurse subfolders) FOR /D - Loop through several folders FOR /L - Loop through a range of numbers FOR /F - Loop through items in a text file FOR /F - Loop through the output of a command Parameters/arguments %~ options FORFILES - Batch process multiple files GOTO - Direct a batch program to jump to a labelled line IF - Conditionally perform a command Powershell: ForEach-Object - Loop for each object in the pipeline Equivalent bash command (Linux): for var in [list]; do - Expand list, and execute commands
Ссылки
Полезн. ссылки по теме for
:
- http://www.cyberforum.ru/cmd-bat/thread877664.html
Шаблон:Windows CMD
-
#1
Циклическиe операции FOR
Командой FOR задаётся список команд, которые выполняются с КАЖДЫМ элементом набора.
Набор* пишется внутри IN (…)
Список команд пишется внутри DO (…)
Командная строка выполняет эти команды раз за разом, при этом текущий элемент набора находится в переменной, заданной после %% (назовём ее переменной цикла).
Например,
FOR %%a IN (C:Users*.txt) DO echo %%a
выведет имена и путь ко всем файлам с расширением .txt в папке C:Users.
* Примеры под спойлером
Для команды For без ключей набором может являться:
1) Маска файлов* (или путь + маска файлов)
— в двойных кавычках, или без них:
IN (*.txt)
Результат: список файлов с расширением .txt в текущем каталоге.
IN (*.txt *.bat)
Результат: список файлов с расширениеми .txt и .bat в текущем каталоге.
IN («C:Folder 1Doc_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
выведет все строки файла 1.txt, который находится в корне диска C.
UseBackQ (Use back quotes) означает, что набор с двойными кавычками* подразумевает передачу в цикл имени файла.
delims= означает, что в переменную %%a будет записана вся строка (без разделения по пробелу или знаку табуляции, т.к. стандартный разделитель заменен на NULL (пустой символ).
В такой вариации:
tokens=* приводит к тому же результату, что и delims=. Означает прекратить разбивку по разделителю после «0-го» токена, т.е. сразу же.
* Этот вариант необходим для работы с файлом, путь или имя которого содержит пробелы.
Можно было не использовать UseBackQ, тогда команда приняла бы вид:
FOR /f "tokens=" %%a IN (C:1.txt) DO echo %%a
но такая конструкция восприняла бы пробел в имени как определение нового файла, поэтому UseBackQ более приемлем.
** Примеры под спойлером
В цикле FOR /F вид задаваемого набора зависит от формы кавычек в IN (…), а также наличия ключевого слова UseBackQ
Виды наборов для FOR /F:
1) Набор файлов (задание маски недопустимо!)
без UseBackQ — задается без кавычек IN (…)
__с UseBackQ — может задаваться как в кавычках так и без них. IN (…) IN («…»)
чтение содержимого файла(ов) построчно в переменную цикла!
Принцип работы:
источником для разбиения по разделителю (delims) является содержимое файла, заданного внутри IN (…) или файлов, если они заданы через пробел.
Исключение:
принятый по-умолчанию разделитель (пробел и знак табуляции) для этой конструкции цикла не применяется.
А что получится, если установить delims= (возле равно — знак пробела) ?
FOR /F "delims= " %%a in (1.txt) do echo %%a
В выводе на экран командой Echo %%a мы получим содержимое файла, где каждая из строк будет напечатана до первого встретившегося пробела.
2) Строка (допускаются практически любые символы)
без UseBackQ — задается с двойными кавычками IN («…»)
__с UseBackQ — задается с одиночными прямыми кавычками IN (‘…’)
3) Команда (сначала выполняется она, а уже ее результаты обрабатываются циклом как строка(-и))
без UseBackQ — задается с одиночными прямыми кавычками IN (‘…’)
__с UseBackQ — задается с одиночными обратными кавычками IN (`…`)
Примеры:
1.1. Чтение файла — Набор файлов
FOR /F %%a IN (c:users1.txt c:users2.txt) do echo.%%a
Результат: выведет подряд содержимое двух файлов — 1.txt и 2.txt из каталога c:users
Прим.: Echo. — с точкой — это обход ошибки, чтобы можно было напечатать пустую строку, точнее строку с пробелами.
1.2. Чтение файла — Набор файлов + UseBackQ
Получаем возможность использовать пробелы.
FOR /F "usebackq" %%a IN ("c:folder 11.txt") do echo.%%a
Результат: выведет содержимое файла 1.txt из каталога c:folder 1
(заметьте, в имени папки есть пробел).
2.1. Строка
FOR /F %%a in ("Каждое слово в отдельную переменную") echo a=%%a; b=%%b; c=%%c; d=%%d; e=%%e
Результат написал(а):
a=Каждое; b=слово; c=в; d=отдельную; e=переменную
2.2. Строка + UseBackQ
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
Сначала выполняется Dir /AD-L, которая выводит информацию о папках в текущем каталоге.
Вот что попадает под разбор циклу:
Далее цикл разбирает каждую строку по пробелам и табуляции на подстроки (токены).
На примере 1-й строки:
1-й токен (%%a)=29.12.2012 …2-й токен (%%b)=15:16 …3-й токен (%%c)=<DIR> …4-й токен (%%d)=Favorites
…
Результат через Echo выводится на экран:
Папка Favorites Дата модификации 29.12.2012. Время 15:16
Папка Links Дата модификации 14.01.2013. Время 01:51
…и т.д.
3.2. Команда + UseBackQ
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 не происходит. Остальная часть подстрок опускается.
Можно проверить:
For /F "tokens=1,2" %%z IN ("1 2") do echo %%A
Бывают случаи, когда требуется разбить строку по специфическому разделителю и при этом выполнить одну и ту же команду над каждой из подстрок (токеном). Кол-во токенов неизвестно.
Метод показал Anonymоus в теме Символ переноса строки в переменной окружения
Алгоритм заключается в замене разделителя на пробел с одновременным заключением каждого токена в двойные кавычки. Далее строка разбирается обычным циклом FOR без ключа.
Более универсальные конструкции на основе FOR /F для работы с файлами/папками строятся путем помещения
в IN (‘…’) команды, результаты от выполнения которой уж затем обрабатываются циклом.
Чаще всего это команда Dir.
1.2. Чтение файла (сложный пример).
Давайте возьмем сложный пример, и раскусим «крепкий орешек»
FOR /F "UseBackQ skip=1 tokens=2 delims=/ eol=" %%X in ("%~dp01.txt") do echo %%X
Имеем в распоряжении файл 1.txt, который находится рядом с батником.
Содержимое файла 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
А второй токен — это подстрока «кода»
Только теперь мы попадаем в тело цикла: Echo %%X
что означает — вывести на экран текст «кода»
С 3-ей строкой потренируйтесь самостоятельно.
Ключ /L
FOR /L %%a IN (0,2,6) DO echo %%a
IN (первое, шаг, последнее)
означает математическое перечисление чисел от первого числа (0), до третьего (6), с шагом, указанным вторым числом (2) в наборе IN (…).
Указанная команда выведет:
Прим.: дробные числа командной строкой не поддерживаются.
-
#2
Продолжение…
Особенности, которые распространяются на циклы FOR
0) Если нужно записать в наборе несколько команд, то используем:
а) знаки амперсанда &, если мы хотим записать все в одну строку:
FOR /L %%a IN (1,1,10) DO echo Найден файл:& echo %%a
б) знаки скобок, если хотим разбить команды в несколько строк для наглядности и удобства:
FOR /L %%a IN (1,1,10) DO (
echo Найден файл:
echo %%a
)
1) Пустые строки в содержимом файлов и выводе команд игнорируются.
2) Если предполагается получение пустого токена, остальные токены смещаются.
К примеру,
имеем файл с содержимым:
file.txt написал(а):
Применим команду:
FOR /F "tokens=1,2,3 delims=/" %%a in (file.txt) do echo a=%%a; b=%%b; c=%%c
Результат будет:
cmd написал(а):
вместо ожидаемого
cmd написал(а):
3) Все специальные (служебные) символы необходимо экранировать (предварять птичкой ^).
Это такие символы, как | = ^ < > &. А также % ! — если они используются не для раскрытия переменной, кроме случая с !, когда не включено удаленное расширение переменных.
Сюда же входит знак кавычки, которая соответствует форме кавычки, применяемой для определения вида набора.
4) Регистр переменной цикла имеет значение.
5) Изменить вручную значение переменной цикла нельзя. Например, set %%A=param не даст эффекта.
6) После выхода из цикла переменная цикла уничтожается.
7) Внутри цикла можно использовать не более 1-го комментария вида :: (иначе, будет критическая ошибка и «вылет» из пакетного файла)
Вместо этого используем Rem.
Внутри цикла можно использовать не более 1-й метки (иначе, будет такой же «вылет»).
Пример максимально допустимой конструкции:
@echo off
for %%n in ( 0 1 2 3 4 5 6 7 8 9 ) do (
:label
echo %%n
:: comment
echo %%n
)
9) Тем не менее из цикла можно безвозвратно выйти на метку Goto metka
а также выйти в подпрограмму и вернутся снова в цикл точно в ту же позицию через команду Call :metka
В конце подпрограммы должна стоять команда Exit /B
10) Для получения значения обычной переменной внутри цикла в случае, если этой переменной было присвоено новое значение внутри тела этого же цикла, необходимо раскрывать переменную через знаки восклицания !variant! — это называется отложенное расширение переменных.
Перед использованием такого способа, его нужно включить, задав в начале пакетного файла команду:
SetLocal EnableDelayedExpansion
Иначе, если использовать обычный способ раскрытия %variant%, мы получим значение переменной, присвоенное ей еще до входа в цикл.
Точно таким же образом (через ! ) необходимо раскрывать переменную времени внутри цикла, т.к. иначе для цикла время «замерзает».
Происходит это потому, что в цикл попадает т.н. «слепок» переменных среды. И работа с ними через % происходит уже как с копией данных, а не актуальными значениями.
11) Когда после IN указана команда, под разбор цикла попадают такие потоки:
1-й поток (StdOut)
с 3-го по 9-й поток (User Stream)
При этом 2-й поток (StdError) отображается на экране сразу после выполнения указанной в цикле команды в IN (…)
2-й поток можно занулить, обычным способом, не забыв экран:
FOR /F %%A IN ('dir %someparam% 2^>nul') do rem
Также можно перенаправить 2-й поток, чтобы он обрабатывался вместе с первым, вместо его вывода на экран:
FOR /F %%A IN ('dir %someparam% 2^>^&1') do rem
Собственно, чтобы наоборот, обрабатывать 2-й поток вместо первого, можно воспользоваться следующей конструкцией:
FOR /F %%A IN ('dir %someparam% 1^>nul 2^>^&3') do rem
12) При запуске цикла из консоли (cmd.exe) переменные цикла нужно указывать без удвоения знака процента %a.
Это же правило касается вызова цикла через Shell-подобные команды на других языках программирования.
13) Переменную цикла нельзя раскрыть внутри строки модификаторов другого цикла:
for /f %%q in (quote) do for /f «usebackq tokens=1* delims=%%q» %%a in («%~dp01.txt») do echo %%a%%b
но есть способ обхода от ComSpec:
Как известно, значение переменной цикла нельзя просто подставить в качестве модификатора в другой, вложенный, цикл:
for /f "tokens=2" %i in ("1 3 5") do @for /f "tokens=%i" %j in ("1 3 5 7 9") do @echo %j
Результатом такой подстановки будет вывод ошибки:
[quote]
Непредвиденное появление: %i".
[/quote]
Если же сделать так:
[code]
for /f "tokens=2" %i in ("1 3 5") do @set x=%i
for /f "tokens=%x%" %j in ("1 3 5 7 9") do @echo %j
то ошибки не будет:
Но как всё же осуществить корректный вывод во вложенном цикле?
Если попробовать присвоить какой-нибудь переменной значение переменной первого цикла, а эатем запустить второй цикл с этой переменной в новом экземпляре интерпретатора с включённым отложенным расширением, то ошибка не исчезает:
for /f "tokens=2" %i in ("1 3 5") do @set x=%i& cmd/v/c for /f "tokens=!x!" %j in ("1 3 5 7 9") do @echo %j
результат:
Непредвиденное появление: !x!».
Оказалось, что это можно сделать проще, а именно просто запустить вложенный цикл в новом экземпляре интерпретатора:
for /f "tokens=2" %i in ("1 3 5") do @cmd/c for /f "tokens=%i" %j in ("1 3 5 7 9") do @echo %j
результат:
Последнее редактирование: 28 Июн 2016
-
#3
Продолжение…
Практические примеры:
1) Использование ключа /D
(спасибо sov44) Переименовать файл в имя папки
2) первый по алфавиту файл
for /F %%i in ("*.txt") do set FILE_NAME=%%~nxi
Берет первый по алфавиту файл, заданный маской *.txt, и сразу выходит из цикла.
Можно также задавать конкретный путь перед маской.
(спасибо pistol за найденный пример.)
3) Использование модификатора %~$ПУТЬ:I для поиска файла в папках, заданных переменной среды Path:
for %%a in ("wmic.exe") do echo %%~s$PATH:a
где:
wmic.exe — наш искомый файл
help написал(а):
Переменная среды ПУТЬ (в примере PATH), и переменная %a
заменяется на полное имя первого найденного файла.
Если переменная ПУТЬ не определена или в результате поиска
не найден ни один файл, то этот модификатор заменяется на пустую строку.
4) Разбивка текста по разделителям
for %%i in (text) do echo %%i
где text — текст, разбивка на итерации которого происходит по знакам:
- пробел
- парные кавычки *
- табуляция
- запятая
- точка с запятой
- знак равенства.
* Примечание от ComSpec:
Надо бы ещё исключить кавычки из перечня разделителей и написать, что парные двойные кавычки, наоборот, объединяют часть строки (или всю строку) вместе с перечисленными разделителями в одно «слово», и при этом сами сохраняются, и если к ним справа или слева примыкает группа символов без разделителей, то она также входит в состав этого «слова».
Исходя из сказанного, надо признать, что данный метод крайне ненадёжен для подсчёта слов (в обычном смысле понятия «слово») в реальных текстах.
5) Удаление лидирующих нулей
:: математические операции со значениями 08 и 09 будут приводить к ошибкам
set /a m=%date:~3,2%
:: поэтому для начала, удаляем лидирующие нули
set m=%date:~3,2%
for /f "tokens=* delims=0" %%j in ("%m%") do set m=%%j
echo %m%
Дополнение от Smitis:
Если количество цифр в числе, в котором надо удалить лидирующие нули, известно заранее, то можно поступить так (для месяца из двух цифр)
:: В вычитаемом числе должно быть столько нулей, сколько цифр исходном числе.
:: Исходное число должно быть не длинее 9-ти разрядов.
set /a m=1%date:~3,2%-100
echo %m%
Можно сразу подставлять такую конструкцию в нужное выражение.
Добавление лидирующих нулей: https://safezone.cc/threads/cmd-dobavit-lidirujuschie-nuli.32940/
6) Распределение итераций цикла for без ключей.
Дополнение: Получение пустых значений токенов в цикле с командой FOR
7) Использование кавычки в роле разделителя
Автор: amel27
for /f tokens^=1^,2^,3^ delims^=^" %%a in ("1""2""3") do echo %%a--%%b--%%с
Циклическая конструкция с использованием сочетания модификаторов
(от ComSpec)
«tokens=* delims=<символы>»
является универсальным «триммером» для удаления любых заявленных символов из начала строки до первого незаявленного символа.
Пример:
for /f "tokens=* delims=0123456789" %i in ("972630014380333075vfh658weghui72qcfgb3658eyfgcb7652qweuy8") do @echo %i
результат:
vfh658weghui72qcfgb3658eyfgcb7652qweuy8
9) получение результата выполнения программы в переменную
(если результатат — 1 строка)
for /f "delims= eol=" %%a in ('file.exe') do set "var=%%a"
Последнее редактирование: 18 Мар 2019