Windows cmd for files in directory

How can I iterate over each file in a directory using a for loop? And how could I tell if a certain entry is a directory or if it's just a file?

How can I iterate over each file in a directory using a for loop?

And how could I tell if a certain entry is a directory or if it’s just a file?

Peter Mortensen's user avatar

asked Sep 26, 2008 at 9:42

Vhaerun's user avatar

3

This lists all the files (and only the files) in the current directory and its subdirectories recursively:

for /r %i in (*) do echo %i

Also if you run that command in a batch file you need to double the % signs.

for /r %%i in (*) do echo %%i

(thanks @agnul)

Sam Sirry's user avatar

answered Sep 26, 2008 at 9:56

jop's user avatar

jopjop

82k10 gold badges55 silver badges52 bronze badges

8

Iterate through…

  • …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

Unfortunately I did not find any way to iterate over files and subdirs at the same time.

Just use cygwin with its bash for much more functionality.

Apart from this: Did you notice, that the buildin help of MS Windows is a great resource for descriptions of cmd’s command line syntax?

Also have a look here: http://technet.microsoft.com/en-us/library/bb490890.aspx

CharlesB's user avatar

CharlesB

84.3k27 gold badges189 silver badges213 bronze badges

answered Sep 26, 2008 at 10:05

Marco's user avatar

MarcoMarco

2,7331 gold badge14 silver badges8 bronze badges

2

To iterate over each file a for loop will work:

for %%f in (directorypath*) do ( something_here )

In my case I also wanted the file content, name, etc.

This lead to a few issues and I thought my use case might help. Here is a loop that reads info from each ‘.txt’ file in a directory and allows you do do something with it (setx for instance).

@ECHO OFF
setlocal enabledelayedexpansion
for %%f in (directorypath*.txt) do (
  set /p val=<%%f
  echo "fullname: %%f"
  echo "name: %%~nf"
  echo "contents: !val!"
)

*Limitation: val<=%%f will only get the first line of the file.

answered May 10, 2016 at 13:54

Aaron Votre's user avatar

Aaron VotreAaron Votre

1,5901 gold badge12 silver badges8 bronze badges

5

There is a subtle difference between running FOR from the command line and from a batch file. In a batch file, you need to put two % characters in front of each variable reference.

From a command line:

FOR %i IN (*) DO ECHO %i

From a batch file:

FOR %%i IN (*) DO ECHO %%i

answered Sep 26, 2008 at 11:52

aphoria's user avatar

aphoriaaphoria

19.5k7 gold badges63 silver badges73 bronze badges

0

This for-loop will list all files in a directory.

pushd somedir
for /f "delims=" %%f in ('dir /b /a-d-h-s') do echo %%f
popd

«delims=» is useful to show long filenames with spaces in it….

‘/b» show only names, not size dates etc..

Some things to know about dir’s /a argument.

  • Any use of «/a» would list everything, including hidden and system attributes.
  • «/ad» would only show subdirectories, including hidden and system ones.
  • «/a-d» argument eliminates content with ‘D’irectory attribute.
  • «/a-d-h-s» will show everything, but entries with ‘D’irectory, ‘H’idden ‘S’ystem attribute.

If you use this on the commandline, remove a «%».

Hope this helps.

answered Jul 7, 2009 at 13:02

Jay's user avatar

JayJay

1,62516 silver badges14 bronze badges

0

%1 refers to the first argument passed in and can’t be used in an iterator.

Try this:

@echo off
for %%i in (*.*) do echo %%i

answered Sep 26, 2008 at 9:52

Sam Meldrum's user avatar

Sam MeldrumSam Meldrum

13.7k6 gold badges33 silver badges40 bronze badges

1

I had trouble getting jop’s answer to work with an absolute path until I found this reference: https://ss64.com/nt/for_r.html

The following example loops through all files in a directory given by the absolute path.

For /R C:absoultepath %%G IN (*.*) do (
  Echo %%G
)

answered Jun 25, 2019 at 20:35

datchung's user avatar

datchungdatchung

3,12624 silver badges24 bronze badges

Here’s my go with comments in the code.

I’m just brushing up by biatch skills so forgive any blatant errors.

I tried to write an all in one solution as best I can with a little modification where the user requires it.

Some important notes: Just change the variable recursive to FALSE if you only want the root directories files and folders processed. Otherwise, it goes through all folders and files.

C&C most welcome…

@echo off
title %~nx0
chcp 65001 >NUL
set "dir=c:users%username%desktop"
::
:: Recursive Loop routine - First Written by Ste on - 2020.01.24 - Rev 1
::
setlocal EnableDelayedExpansion
rem THIS IS A RECURSIVE SOLUTION [ALBEIT IF YOU CHANGE THE RECURSIVE TO FALSE, NO]
rem By removing the /s switch from the first loop if you want to loop through
rem the base folder only.
set recursive=TRUE
if %recursive% equ TRUE ( set recursive=/s ) else ( set recursive= )
endlocal & set recursive=%recursive%
cd /d %dir%
echo Directory %cd%
for %%F in ("*") do (echo    → %%F)                                 %= Loop through the current directory. =%
for /f "delims==" %%D in ('dir "%dir%" /ad /b %recursive%') do (    %= Loop through the sub-directories only if the recursive variable is TRUE. =%
  echo Directory %%D
  echo %recursive% | find "/s" >NUL 2>NUL && (
    pushd %%D
    cd /d %%D
    for /f "delims==" %%F in ('dir "*" /b') do (                      %= Then loop through each pushd' folder and work on the files and folders =%
      echo %%~aF | find /v "d" >NUL 2>NUL && (                        %= This will weed out the directories by checking their attributes for the lack of 'd' with the /v switch therefore you can now work on the files only. =%
      rem You can do stuff to your files here.
      rem Below are some examples of the info you can get by expanding the %%F variable.
      rem Uncomment one at a time to see the results.
      echo    → %%~F           &rem expands %%F removing any surrounding quotes (")
      rem echo    → %%~dF          &rem expands %%F to a drive letter only
      rem echo    → %%~fF          &rem expands %%F to a fully qualified path name
      rem echo    → %%~pF          &rem expands %%A to a path only
      rem echo    → %%~nF          &rem expands %%F to a file name only
      rem echo    → %%~xF          &rem expands %%F to a file extension only
      rem echo    → %%~sF          &rem expanded path contains short names only
      rem echo    → %%~aF          &rem expands %%F to file attributes of file
      rem echo    → %%~tF          &rem expands %%F to date/time of file
      rem echo    → %%~zF          &rem expands %%F to size of file
      rem echo    → %%~dpF         &rem expands %%F to a drive letter and path only
      rem echo    → %%~nxF         &rem expands %%F to a file name and extension only
      rem echo    → %%~fsF         &rem expands %%F to a full path name with short names only
      rem echo    → %%~dp$dir:F    &rem searches the directories listed in the 'dir' environment variable and expands %%F to the fully qualified name of the first one found. If the environment variable name is not defined or the file is not found by the search, then this modifier expands to the empty string
      rem echo    → %%~ftzaF       &rem expands %%F to a DIR like output line
      )
      )
    popd
    )
  )
echo/ & pause & cls

answered Jan 24, 2020 at 22:29

Ste's user avatar

SteSte

1,5601 gold badge14 silver badges24 bronze badges

To iterate through all files and folders you can use

for /F "delims=" %%a in ('dir /b /s') do echo %%a

To iterate through all folders only not with files, then you can use

for /F "delims=" %%a in ('dir /a:d /b /s') do echo %%a

Where /s will give all results throughout the directory tree in unlimited depth. You can skip /s if you want to iterate through the content of that folder not their sub folder

Implementing search in iteration

To iterate through a particular named files and folders you can search for the name and iterate using for loop

for /F "delims=" %%a in ('dir "file or folder name" /b /s') do echo %%a

To iterate through a particular named folders/directories and not files, then use /AD in the same command

for /F "delims=" %%a in ('dir "folder name" /b /AD /s') do echo %%a

answered Feb 28, 2019 at 12:09

jafarbtech's user avatar

jafarbtechjafarbtech

6,6521 gold badge35 silver badges55 bronze badges

for %1 in (*.*) do echo %1

Try «HELP FOR» in cmd for a full guide

This is the guide for XP commands. http://www.ss64.com/nt/

answered Sep 26, 2008 at 9:48

Axeman's user avatar

AxemanAxeman

3491 silver badge7 bronze badges

0

The following code creates a file Named «AllFilesInCurrentDirectorylist.txt» in the current Directory, which contains the list of all files (Only Files) in the current Directory. Check it out

dir /b /a-d > AllFilesInCurrentDirectorylist.txt

answered Sep 28, 2010 at 9:21

Ankur's user avatar

AnkurAnkur

1,23819 silver badges22 bronze badges

It could also use the forfiles command:

forfiles /s 

and also check if it is a directory

forfiles /p c: /s /m *.* /c "cmd /c if @isdir==true echo @file is a directory"

Peter Mortensen's user avatar

answered Sep 11, 2014 at 14:41

Max's user avatar

MaxMax

4444 silver badges10 bronze badges

1

I would use vbscript (Windows Scripting Host), because in batch I’m sure you cannot tell that a name is a file or a directory.

In vbs, it can be something like this:

Dim fileSystemObject
Set fileSystemObject = CreateObject("Scripting.FileSystemObject")

Dim mainFolder
Set mainFolder = fileSystemObject.GetFolder(myFolder)

Dim files
Set files = mainFolder.Files

For Each file in files
...
Next

Dim subFolders
Set subFolders = mainFolder.SubFolders

For Each folder in subFolders
...
Next

Check FileSystemObject on MSDN.

answered Sep 26, 2008 at 9:56

Biri's user avatar

BiriBiri

7,0697 gold badges37 silver badges52 bronze badges

4

I use the xcopy command with the /L option to get the file names. So if you want to get either a directory or all the files in the subdirectory you could do something like this:

for /f "delims=" %%a IN ('xcopy "D:*.pdf" c: /l') do echo %%a

I just use the c: as the destination because it always exists on windows systems and it is not copying so it does not matter. if you want the subdirectories too just use /s option on the end. You can also use the other switches of xcopy if you need them for other reasons.

competent_tech's user avatar

answered Dec 29, 2012 at 19:27

Knoots's user avatar

Try this to test if a file is a directory:

FOR /F "delims=" %I IN ('DIR /B /AD "filename" 2^>^&1 ^>NUL') DO IF "%I" == "File Not Found" ECHO Not a directory

This only will tell you whether a file is NOT a directory, which will also be true if the file doesn’t exist, so be sure to check for that first if you need to. The carets (^) are used to escape the redirect symbols and the file listing output is redirected to NUL to prevent it from being displayed, while the DIR listing’s error output is redirected to the output so you can test against DIR’s message «File Not Found».

Peter Mortensen's user avatar

answered Jan 4, 2011 at 17:55

sugerfunk's user avatar

0

try this:

::Example directory
set SetupDir=C:Users

::Loop in the folder with "/r" to search in recursive folders, %%f being a loop ::variable 
for /r "%SetupDir%" %%f in (*.msi *.exe) do set /a counter+=1

echo there are %counter% files in your folder

it counts .msi and .exe files in your directory (and in the sub directory). So it also makes the difference between folders and files as executables.

Just add an extension (.pptx .docx ..) if you need to filter other files in the loop

answered Dec 2, 2016 at 10:38

Littlepony's user avatar

In my case I had to delete all the files and folders underneath a temp folder. So this is how I ended up doing it. I had to run two loops one for file and one for folders. If files or folders have spaces in their names then you have to use » «

cd %USERPROFILE%AppDataLocalTemp
rem files only
for /r %%a in (*) do (
echo deleting file "%%a" ...
if exist "%%a" del /s /q "%%a"
)
rem folders only
for /D %%a in (*) do (
echo deleting folder "%%a" ...
if exist "%%a" rmdir /s /q "%%a"
)

answered Sep 26, 2018 at 17:54

Sam B's user avatar

Sam BSam B

27k15 gold badges83 silver badges120 bronze badges

I’m assuming this is fairly easy to do, but I have zero experience with Windows’s command line utilities. Basically, I need to iterate over all files in a directory (great if it can do sub-directories, but I can run it on each of the 5 directories if need be), get the name as a variable, and have it run

"C:Program FilesImageMagick-6.7.6-Q16convert.exe" -compress LZW 
   -colorspace Gray -colors 32 file_var file_var

I saw Dynamically name files in a command prompt for loop. Would I be able to use that (swapping the SET… with the above command)? The space on the computer in question is beyond limited so I can’t perform a backup prior to running this at this stage (bad, I know).

Community's user avatar

asked May 14, 2012 at 3:03

Robert's user avatar

3

Weird, there was a response that had the recursive part.

Well, per How to Loop Through Files Matching Wildcard in Batch File, I was able to achieve this. Here is how it was performed:

 cd path_to_root
 for /R %%f in (*.tif) do (
 "C:Program FilesImageMagick-6.7.6-Q16convert.exe" -compress LZW 
    -colorspace Gray -colors 32 "%%f" "%%f"
 )

Community's user avatar

answered Mar 4, 2013 at 14:21

Robert's user avatar

RobertRobert

5011 gold badge5 silver badges16 bronze badges

1

Open PowerShell

$files = Get-ChildItem -Recurse 
foreach ($file in $files){
    c:windowsSystem32notepad.exe $file.FullName
}

Get-ChildItem retrieves a list of files as objects from the current subdirectory. «-recurse» will include sub-directories. This places it into an array $Files.

The foreach loop cycles through each file and calls notepad with the commandline argument of the full file-name path to each file.

CAUTION: Test the above code in a directory with a few small text files, as it will open up an instance of Notepad for each file.

That should give you an idea of how to go about what you’re looking to do.

answered Mar 2, 2013 at 21:45

Bye's user avatar

ByeBye

3511 gold badge3 silver badges8 bronze badges

0

Learn how to use for command to iterate over a list of items and run commands on each of them. We can run a command for each file in a directory, for example.

The simplest form of for command is:

for %i in (set) do command command-arguments

Here set means the list of variants for which the command needs to be run. I’m not listing the for loop’s full options here as same can be found by running the command ‘for /? ‘.   I have explained below with examples as to how to use for loop in different use cases.

Run command for each file

You want to run an application/command on selective files in a directory. You can use for command for this use case as below.

for /F %i in ('command to get files list') do command %i

For example, you want to open all the log files using notepad application.

for /F %i in ('dir /b *.log') do notepad %i

Here dir /b *.log retrieves the list of all log files. For command iterates over the list and then opens them in notepad.

Run command for each user

You have a list of login names whose accounts need to be deleted from the system. Let’s say the user names are user1, user2, user3, user4, user5, user6. To delete all these user accounts in a single step we can run the below command.

for %i in (user1 user2 user3 user4 user5 user6) do net user /delete %i

If the list of user accounts is stored in a file then we can delete the accounts using the below command.

for /F %i in (filename) do net user /delete %i

Similarly, we can add new user accounts in batch using for command.

Select columns from a text file (Similar to Linux ‘cut’ command)

If you have a text file with multiple columns, and if you want to filter out certain unwanted columns from the file, you can do it using for command easily.
Let’s say my file has 4 columns separated with space as below.

abcd efgh ijkl mnop
qrst uvwx yz1 adef
efsa erafa afaf affaf
....

Now to print only the columns 2 and 4, I can use the below command.

 for /F "tokens=2,4" %i in (test.txt) do @echo %i %j

You can redirect the output from the above command to a new text file using the operator pipe(‘|’)

If the file is separated with with comma(‘,’), as in CSV files, we can use the below command.

for /F "tokens=2,4 delims=," %i in (test.txt) do @echo %i %j

If you want to retain the comma(,) between the columns, you can add it as below.

for /F "tokens=2,4 delims=," %i in (test.txt) do @echo %i,%j

В этой статье мы рассмотрим как используется цикл for в командной строке (cmd) для групповой работы с каталогами. Как уже упоминалось, логику работы cmd цикла можно менять с помощью ключей, так, для обработки каталогов применяется ключ /D.

Стоит учитывать тот факт, что в данном случаем мы можем обработать все входящие на один уровень папки для заданного каталога, но не дальше, для обработки полный структуры, используется другой ключ — /R, примеры работы с которым мы рассмотрим по ходу статьи.

Фактически, с помощью цикла cmd for можно получить слепок всего дерева каталогов для заданного диска, и в групповом порядке их обработать.

Cmd цикл for – обработка корневых и вложенных папок

Для работы с каталогами цикл принимает следующий вид:

for /D %%переменная in (набор_каталогов) do (оператор)

Фактически, тут логика работы аналогична той, что используется при работе с файлами. Переменная набор_каталогов содержит путь к папке, содержимое которой нужно обработать. Только помните, что в данном случае мы получаем не список файлов, а каталогов. Мы также можем указать шаблон для поиска:

@echo offfor/d %%B in(%SystemRoot%*)doecho%%B

В данном случае функция echo выведет список всех папок, которые есть в системном каталоге (путь к нему, хранится в переменной (%SystemRoot%). Или такой вариант:

@echo offfor/d %%B in(%SystemRoot%S*)doecho%%B

Тут мы получим список лишь тех папок, имена которых начинаются на S.

Как и с файлами, можно указать список, используя в качестве разделителя пробел:

@echo offfor/D %%B in(%SystemRoot%*%TEMP%*)doecho%%B

Тут происходит вывод всех папок из системной и временной папки (переменная окружения %TEMP%).

А вот такая запись:

for/d %%B in(%SystemRoot%)doecho%%B

выведет путь к системному каталогу, заданному в переменной окружения %SystemRoot%. Аналогичный результат можно получить прописав:

или

в первом случае мы используем функцию echo, а во втором ключевое слово set.

Можно совмещать различные вариации цикла cmd (командной строки), так, можно попробовать получить список всех заданных файлов, которые есть во вложенных каталогах текущей папки, например:

@echo offsetwork_dir=d:workfor/d %%B in(%work_dir%*)do(for%%C in("%%B*.txt")doecho%%C)setwork_dir=

В данном примере вначале сценария создается переменная work_dir, который присваивается путь d:work. Далее следует cmd цикл с ключом /d. Переменная B будет хранить пути ко всем вложенным каталога папки d:work. При нахождении вложенной папки идет обработка нового цикла cmd, который уже отвечает за поиск текстовых файлов в найденном подкаталоге. Результат как всегда выводится с помощью функции echo. В конце сценария мы удаляем переменную work_dir из переменной среды.

Как вы уже заметили, ключ /d в позволяет получить список вложенных каталогов с одним уровнем, но не позволяет получить полную структуру всех вложенных папок или файлов.

Cmd цикл for – обработка полной структуры

Для решения этой задачи, используется следующий синтаксис:

for /R [путь] %%переменная in (набор_файлов) do (оператор)

Видим, что тут уже фигурирует ключ R, после которого можно указать путь к папке или диску, структуру которого надо обработать. Если не указывать путь, то произойдет обработка текущей папки. Как и прежде, перед ключевым словом in нужно прописать переменную инициализации, а переменная набор_файлов может хранить имя файла или их список, заданный с помощь шаблона или через пробел:

@echo offfor/R %SystemRoot%%%B in(*.vbs *.js)doecho%%B

В данном случае происходит поиск файлов с расширением .vbs и .js во всей структуре системного каталога, заданного переменной окружения SystemRoot.

Можно даже извлечь список всех вложенных каталогов для заданной структуры:

@echo offfor/R %SystemRoot%/d %%B in(*)doecho%%B

В данном случае, мы использовали оба ключа /R и /D, а символ звездочки указывает на то, что нужно извлечь список абсолютно всех вложенных папок.

Dragokas


  • #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, которая выводит информацию о папках в текущем каталоге.
Вот что попадает под разбор циклу:

231664d1359927854

Далее цикл разбирает каждую строку по пробелам и табуляции на подстроки (токены).
На примере 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. Чтение файла (сложный пример).
Давайте возьмем сложный пример, и раскусим «крепкий орешек»

smile3.gif

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) Итак, первая строка так и называется «первая строка»

smile3.gif

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

IN (первое, шаг, последнее)
означает математическое перечисление чисел от первого числа (0), до третьего (6), с шагом, указанным вторым числом (2) в наборе IN (…).

Указанная команда выведет:

Прим.: дробные числа командной строкой не поддерживаются.

Dragokas


  • #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.

8) Внутри цикла можно использовать не более 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

Dragokas


  • #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--%%с

8) Циклическая конструкция с использованием сочетания модификаторов
(от 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

04.02.2013, 00:56. Показов 289221. Ответов 16


Вдохновившись сообщением от FraidZZ, написал мини-статейку, основанную на изложенных им положениях.

Заметки

Циклическиe операции FOR

Командой FOR задаётся список команд, которые выполняются с КАЖДЫМ элементом набора.
Набор* пишется внутри IN (…)
Список команд пишется внутри DO (…)
Командная строка выполняет эти команды раз за разом, при этом текущий элемент набора находится в переменной, заданной после %% (назовём ее переменной цикла).

Например,

Windows Batch file
1
FOR %%a IN (C:Users*.txt) DO echo %%a

выведет имена и путь ко всем файлам с расширением .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
1
FOR %%a IN (гитара рыбка) do echo Моя %%a

Результат:

Если мы хотим, чтобы какая-то из строк не «билась» по пробелам, укажем ее в двойных кавычках:

Windows Batch file
1
FOR %%a IN (гитара "дорогая рыбка") do echo Моя %%~a

Результат:

Моя гитара
Моя дорогая рыбка

При этом, чтобы не выводились сами кавычки «» мы используем модификатор* ~ (тильда) при раскрытии переменной цикла %%~a

*О других модификаторах переменной цикла можно почитать здесь и здесь.

Не по теме:

3) еще есть смешанный тип. Это когда в наборе стоит маска (1-й описанный тип), а через пробел Строка (2 тип)… ведет себя вполне ожидаемо, но вряд ли найдет себе применение.

О наборах для FOR с ключем /F далее в нижнем спойлере.

Ключ /F часто используется для построчного разбора файла, т.е.

Windows Batch file
1
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, тогда команда приняла бы вид:

Windows Batch file
1
FOR /f "tokens=" %%a IN (C:1.txt) DO echo %%a

но такая конструкция восприняла бы пробел в имени как определение нового файла, поэтому UseBackQ более приемлем.

** Примеры под спойлером

Виды наборов для FOR /F

В цикле FOR /F вид задаваемого набора зависит от формы кавычек в IN (…), а также наличия ключевого слова UseBackQ

Виды наборов для FOR /F:
1) Набор файлов (задание маски недопустимо!)

без UseBackQ — задается без кавычек IN (…)

__с UseBackQ — может задаваться как в кавычках так и без них. IN (…) IN («…»)

Специфика работы


Функционал:

чтение содержимого файла(ов) построчно в переменную цикла!

Принцип работы:

источником для разбиения по разделителю (delims) является содержимое файла, заданного внутри IN (…) или файлов, если они заданы через пробел.

Исключение:

принятый по-умолчанию разделитель (пробел и знак табуляции) для этой конструкции цикла не применяется.

А что получится, если установить delims= (возле равно — знак пробела) ?

Windows Batch file
1
FOR /F "delims= " %%a in (1.txt) do echo %%a

В выводе на экран командой Echo %%a мы получим содержимое файла, где каждая из строк будет напечатана до первого встретившегося пробела.
.

2) Строка (допускаются практически любые символы)

без UseBackQ — задается с двойными кавычками IN («…»)

__с UseBackQ — задается с одиночными прямыми кавычками IN (‘…’)

3) Команда (сначала выполняется она, а уже ее результаты обрабатываются циклом как строка(-и))

без UseBackQ — задается с одиночными прямыми кавычками IN (‘…’)

__с UseBackQ — задается с одиночными обратными кавычками IN (`…`)

Примеры:

1.1. Чтение файла — Набор файлов

Windows Batch file
1
FOR /F %%a IN (c:users1.txt c:users2.txt) do echo.%%a

Результат: выведет подряд содержимое двух файлов — 1.txt и 2.txt из каталога c:users
Прим.: Echo. — с точкой — это обход ошибки, чтобы можно было напечатать пустую строку, точнее строку с пробелами.

1.2. Чтение файла — Набор файлов + UseBackQ
Получаем возможность использовать пробелы.

Windows Batch file
1
FOR /F "usebackq" %%a IN ("c:folder 11.txt") do echo.%%a

Результат: выведет содержимое файла 1.txt из каталога c:folder 1
(заметьте, в имени папки есть пробел).

2.1. Строка

Windows Batch file
1
FOR /F %%a in ("Каждое слово в отдельную переменную") DO echo a=%%a; b=%%b; c=%%c; d=%%d; e=%%e

Цитата
Сообщение от Результат

a=Каждое; b=слово; c=в; d=отдельную; e=переменную

2.2. Строка + UseBackQ

Windows Batch file
1
FOR /F "UseBackQ" %%a in ('Каждое слово в отдельную переменную') DO echo a=%%a; b=%%b; c=%%c; d=%%d; e=%%e

Результат такой же.

3.1. Команда

Windows Batch file
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

Windows Batch file
1
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 %%

Т.е.

Windows Batch file
1
FOR /F "tokens=1,2" %%a IN ("гитара рыбка") do echo Моя %%a и моя %%b.

Результат:

Обратите внимание: по умолчанию, цикл выдаёт в результатах только 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
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
А второй токен — это подстрока «кода»

8) Только теперь мы попадаем в тело цикла: Echo %%X
что означает — вывести на экран текст «кода»

С 3-ей строкой потренируйтесь самостоятельно.

Вот такой результат окажется на экране:

Ключ /L

Windows Batch file
1
FOR /L %%a IN (0,2,6) DO echo %%a

IN (первое, шаг, последнее)
означает математическое перечисление чисел от первого числа (0), до третьего (6), с шагом, указанным вторым числом (2) в наборе IN (…).

Указанная команда выведет:

Прим.: дробные числа командной строкой не поддерживаются.

Миниатюры

Циклические операции и примеры (команда FOR) * [Статья]
 



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

title description ms.topic ms.assetid ms.author author manager ms.date

forfiles

Reference article for forfiles command, which selects and runs a command on a file or set of files.

reference

43f6b004-446d-4fdd-91c5-5653613524a4

jgerend

JasonGerend

mtillman

05/20/2020

Selects and runs a command on a file or set of files. This command is most commonly used in batch files.

Syntax

forfiles [/P pathname] [/M searchmask] [/S] [/C command] [/D [+ | -] [{<date> | <days>}]]

Parameters

Parameter Description
/P <pathname> Specifies the path from which to start the search. By default, searching starts in the current working directory.
/M <searchmask> Searches files according to the specified search mask. The default searchmask is *.
/S Instructs the forfiles command to search in subdirectories recursively.
/C <command> Runs the specified command on each file. Command strings should be wrapped in double quotes. The default command is "cmd /c echo @file".
/D `[{+|-}][{ }]`
/? Displays the help text in the cmd window.

Remarks

  • The forfiles /S command is similar to dir /S.

  • You can use the following variables in the command string as specified by the /C command-line option:

    Variable Description
    @FILE File name.
    @FNAME File name without extension.
    @EXT File name extension.
    @PATH Full path of the file.
    @RELPATH Relative path of the file.
    @ISDIR Evaluates to TRUE if a file type is a directory. Otherwise, this variable evaluates to FALSE.
    @FSIZE File size, in bytes.
    @FDATE Last modified date stamp on the file.
    @FTIME Last modified time stamp on the file.
  • The forfiles command lets you run a command on or pass arguments to multiple files. For example, you could run the type command on all files in a tree with the .txt file name extension. Or you could execute every batch file (*.bat) on drive C, with the file name Myinput.txt as the first argument.

  • This command can:

    • Select files by an absolute date or a relative date by using the /d parameter.

    • Build an archive tree of files by using variables such as @FSIZE and @FDATE.

    • Differentiate files from directories by using the @ISDIR variable.

    • Include special characters in the command line by using the hexadecimal code for the character, in 0xHH format (for example, 0x09 for a tab).

  • This command works by implementing the recurse subdirectories flag on tools that are designed to process only a single file.

Examples

To list all of the batch files on drive C, type:

forfiles /P c: /S /M *.bat /C "cmd /c echo @file is a batch file"

To list all of the directories on drive C, type:

forfiles /P c: /S /M * /C "cmd /c if @isdir==TRUE echo @file is a directory"

To list all of the files in the current directory that are at least one year old, type:

forfiles /S /M *.* /D -365 /C "cmd /c echo @file is at least one year old."

To display the text file is outdated for each of the files in the current directory that are older than January 1, 2007, type:

forfiles /S /M *.* /D -01/01/2007 /C "cmd /c echo @file is outdated."

To list the file name extensions of all the files in the current directory in column format, and add a tab before the extension, type:

forfiles /S /M *.* /C "cmd /c echo The extension of @file is 0x09@ext"

Related links

  • Command-Line Syntax Key

Понравилась статья? Поделить с друзьями:
  • Windows bootable image creator как пользоваться
  • Windows can t verify the publisher of this driver software
  • Windows cmd delete folder with files
  • Windows boot manager это жесткий диск
  • Windows can t be installed on this drive