首页 > 教程攻略 > ai教程 >批处理命令 For循环命令详解

批处理命令 For循环命令详解

来源:互联网 时间:2026-07-02 07:21:05

批处理 for 命令详解

FOR 这条命令在批处理中通常被用来处理文本,但它的本事可不只这些——还有很多实用的功能等着我们去发掘。先看看它的基本格式(这里引用批处理中的格式,直接在命令行使用只需要一个 % 号):

FOR 参数 %%变量名 IN (相关文件或命令) DO 执行的命令

参数

:FOR 有四个参数 /d/l/r/f,具体作用下面通过例子说明。

%%变量名

:这个变量名可以是小写 a~z 或大写 A~Z,区分大小写,FOR 会把每个读取到的值赋给变量。

IN

:照写。

(相关文件或命令)

:FOR 要把什么东西读取然后赋值给变量,看后面的例子。

do

:照写。

执行的命令

:对每个变量的值要执行什么操作就写在这。

也可以在 CMD 下输入 for /? 查看系统提供的帮助,对照一下:

FOR %%variable IN (set) DO command [command-parameters]

%%variable 指定一个单一字母可替换的参数。
(set) 指定一个或一组文件,可以使用通配符。
command 指定对每个文件执行的命令。
command-parameters 为特定命令指定参数或命令行开关。

现在开始逐项讲解每个参数的含义。

/d 参数

系统帮助格式:FOR /D %%variable IN (set) DO command

仅为目录

:如果 Set(也就是上面说的“相关文件或命令”)包含通配符(*?),将对与 Set 相匹配的每个目录(而不是目录中的文件组)执行指定的 Command。该参数主要用于目录搜索,不会搜索文件。看一个例子:

@echo off
for /d %%i in (*) do @echo %%i
pause

把这个 BAT 保存在 C 盘根目录执行,就会把 C 盘根目录下的全部目录名字打印出来,而文件名字一个也不会显示。

再来看一个:如果要打印当前目录下名字只有 1~3 个字母的目录:

@echo off
for /d %%i in (???) do @echo %%i
pause

如果当前目录下存在名字长度 1~3 个字母的目录,就会显示出来。

思考题:

@echo off
for /d %%i in (window?) do @echo %%i
pause

保存到 C 盘下执行,会显示什么呢?不妨自己试试看。
注意:/d 参数只能显示当前目录下的目录名字,这一点要牢记。

/r 参数

系统帮助格式:FOR /R [[drive:]path] %%variable IN (set) DO command

递归

:进入根目录树 [Drive:]Path,在树的每个目录中执行 FOR 语句。如果在 /R 后没有指定目录,则认为当前目录。如果 Set 只是一个句点(.),则只枚举目录树。

之前提到 /d 只能显示当前路径下的目录名字,而 /r 比它强大得多——它可以把当前或指定路径下的文件名字全部读取(注意是文件名字)。看例子:

@echo off
for /r c:\ %%i in (*.exe) do @echo %%i
pause

把这个 BAT 保存到 D 盘任意位置执行,会看到它把 C 盘根目录以及每个子目录下面的所有 EXE 文件都列出来了。这里的 c:\ 就是搜索路径。

再来看一个:

@echo off
for /r %%i in (*.exe) do @echo %%i
pause

这次没有指定搜索路径,就会以当前目录为搜索路径。比如把 BAT 放在 d:\test 下执行,它会列出 d:\test 及其所有子目录下的 EXE 文件。

/l 参数

系统帮助格式:for /L %%Variable in (Start#,Step#,End#) do Command

迭代数值范围

:使用迭代变量设置起始值 (Start#),然后逐步执行一组范围的值,直到该值超过所设置的终止值 (End#)。/L 会通过比较 Start# 和 End# 来执行迭代——如果 Start# 小于 End#,就执行命令;如果迭代变量超过 End#,则命令解释程序退出此循环。也可以使用负的 Step# 递减。例如 (1,1,5) 生成序列 1 2 3 4 5,而 (5,-1,1) 生成序列 5 4 3 2 1。

举个例子:

@echo off
for /l %%i in (1,1,5) do @echo %%i
pause

执行后会打印 1 2 3 4 5 共五个数字。(1,1,5) 表示从 1 开始,每次加 1,直到 5 终止。

再看这个:

@echo off
for /l %%i in (1,1,5) do start cmd
pause

执行后会发现多了 5 个 CMD 窗口。如果把 (1,1,5) 改成 (1,1,65535),会打开 65535 个 CMD 窗口……不强制关机的话很难顶住。

当然,也可以把 start cmd 换成 md %%i,这样就会建立指定数量的目录,名字为 1~65535。

/f 参数(核心功能)

包含 /f 的 FOR 命令使用最多,也最为强大。用法如下:

FOR /F ["options"] %%i IN (file) DO command
FOR /F ["options"] %%i IN ("string") DO command
FOR /F ["options"] %%i IN ('command') DO command

这个参数主要用于处理文件和一些命令的输出结果。

  • file 代表一个或多个文件
  • string 代表字符串
  • command 代表命令
  • ["options"] 可选

对于 FOR /F %%i IN (file) DO commandfile 为文件名。按照官方的说法,FOR 会依次将 file 中的文件打开,并且在处理下一个文件之前将每个文件读取到内存,按照每一行分成一个一个的元素,忽略空白的行。

假设文件 a.txt 中有如下内容:

第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列

想显示 a.txt 中的内容,通常用 type a.txt,但 FOR 也可以做到:

for /f %%i in (a.txt) do echo %%i

这里会先打开 a.txt,读出所有内容,把每一行作为一个元素,生成集合:

{“第1行第1列 第1行第2列 第1行第3列”,
 “第2行第1列 第2行第2列 第2行第3列”,
 “第3行第1列 第3行第2列 第3行第3列”}

集合中只有 3 个元素,用 %%i 依次代替每个元素,然后执行 do 后面的命令。

为了加深理解,可以执行下面两个命令对比效果:

for /f %%i in (a.txt) do echo %%i   ' 会显示 a.txt 内容
for %%i in (a.txt) do echo %%i     ' 只显示 a.txt 这个名字,不读取内容

默认情况下,for /f 把每一行作为一个元素。但如果想把每一行再分解成更小的内容呢?FOR 提供了 delimstokens 参数来实现。

delims 的作用

:告诉 FOR 每一行用什么作为分隔符,默认分隔符是空格和 Tab 键。例如,还是上面的 a.txt:

for /f "delims= " %%i in (a.txt) do echo %%i

显示结果为:

第1行第1列
第2行第1列
第3行第1列

因为 delims= 后面跟了一个空格,表示把每一行按空格分割,默认只取分割后的第一个元素。

tokens 的作用

:通过 delims 将每一行分成更小的元素后,由 tokens 控制取哪一个或哪几个。例如取第二列:

for /f "tokens=2 delims= " %%i in (a.txt) do echo %%i

执行结果:

第1行第2列
第2行第2列
第3行第2列

如果要显示第三列,就换成 tokens=3。同时 tokens 支持通配符 * 以及限定范围。如果要显示第二列和第三列,可以写成 tokens=2,3tokens=2-3

for /f "tokens=2,3 delims= " %%i in (a.txt) do echo %%i %%j

这里多了一个 %%j,因为 tokens 取两列,用 %%i 替换第二列,用 %%j 替换第三列(必须按英文字母顺序)。

执行结果为:

第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列

通配符 * 表示把这一行的剩余部分当作一个元素。例如:

for /f "tokens=* delims= " %%i in (a.txt) do echo %%i

执行结果与不加任何参数完全一致。

再看:

for /f "tokens=2,* delims= " %%i in (a.txt) do echo %%i %%j

执行结果:

第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列

这里 %%i 代替第二列,%%j 代替剩余部分。

还有两个简单的选项:

skip

eol

  • skip=n

    :忽略文件的前 n 行。例如 skip=2 表示跳过前两行:
for /f "skip=2 tokens=*" %%i in (a.txt) do echo %%i

结果为:第3行第1列 第3行第2列 第3行第3列。如果不加 tokens=*,只会显示 第3行第1列

  • eol=c

    :指定行注释字符,以该字符开头的行会被忽略。例如 a.txt 内容变为:
.第1行第1列 第1行第2列 第1行第3列
.第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列

执行:

for /f "eol=. tokens=*" %%i in (a.txt) do echo %%i

结果为:第3行第1列 第3行第2列 第3行第3列


批处理命令 For循环命令详解

终极 dos 批处理循环命令详解

格式:FOR [参数] %%变量名 IN (相关文件或命令) DO 执行的命令
作用:对一个或一组文件、字符串或命令结果中的每一个对象执行特定命令,达到想要的结果。
注意:在批处理文件中使用 FOR 命令时,指定变量请使用 %%variable,不要用 %variable。变量名称区分大小写,所以 %i 不同于 %I
关于参数:FOR 命令可以带参数或不带参数,带参数时支持 /d/l/r/f。下面分别说明。

无参数时

格式:FOR %variable IN (set) DO command [command-parameters]

示例:

for %%i in (t*.*) do echo %%i   '显示当前目录下与 t*.* 匹配的文件(只显示文件名,不显示路径)
for %%i in (d:\mydocuments\*.doc) do @echo %%i   '显示 d:\mydocuments 目录下与 *.doc 匹配的文件

/d 参数

格式:FOR /D %variable IN (set) DO command [command-parameters]
用于目录搜索,不搜索文件,且只能显示当前目录下的目录名字(不会搜索子目录)。

示例:

for /d %%i in (c:\*) do echo %%i   '显示 C 盘根目录下的所有目录
for /d %%i in (???) do echo %%i   '显示当前目录下名字只有1~3个字母的目录

/r 参数

格式:FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
搜索指定路径及所有子目录中与 set 相符合的所有文件。

  1. 如果 set 中包含通配符(?*),则列举 /R 参数指定的目录及其所有子目录中匹配的文件。
  2. 如果 set 是具体文件名(不含通配符),则枚举该目录树(列出该目录及其所有子目录),并在后面加上具体的文件名,不管该文件是否存在。

示例:

for /r c:\ %%i in (*.exe) do echo %%i   '列出 C 盘所有子目录下的 EXE 文件
for /r c:\ %%i in (boot.ini) do echo %%i   '枚举 C 盘所有目录(实际未必存在该文件)
for /r c:\ %%i in (boot.ini) do if exist %%i echo %%i   '很好的搜索命令,只列出 boot.ini 存在的目录

/l 参数

格式:FOR /L %variable IN (start,step,end) DO command [command-parameters]
以增量形式从开始到结束的数字序列。

示例:

for /l %%i in (1,1,5) do @echo %%i   '输出 1 2 3 4 5
for /l %%i in (1,2,10) do @echo %%i   '输出 1 3 5 7 9
for /l %%i in (100,-20,1) do @echo %%i   '输出 100 80 60 40 20
for /l %%i in (1,1,5) do start cmd   '打开5个CMD窗口
for /l %%i in (1,1,5) do md %%i   '建立1~5共5个文件夹
for /l %%i in (1,1,5) do rd /q %%i   '删除1~5共5个文件夹

/f 参数(详细)

这个参数最复杂,选项也最多。简单说:for /f 可以分析文件内容、字符串内容或某命令输出的结果,并通过 options 得到想要的结果。

格式:

FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]

如果有 usebackq 选项:

FOR /F ["options"] %variable IN ("file-set") DO command [command-parameters]
FOR /F ["options"] %variable IN ('string') DO command [command-parameters]
FOR /F ["options"] %variable IN (`command`) DO command [command-parameters]

(注意:这里的反引号 ` 是键盘上数字1左面的键)

OPTION 关键字详解:

  • eol=c:指定行注释字符,例如 eol=; 表示忽略以分号开头的行。
  • skip=n:跳过文件前 n 行。
  • delims=xxx:指定分隔符集,替换默认的空格和 Tab。例如 delims=, 表示用逗号和空格作为分隔符。
  • tokens=x,y,m-n:指定每行的哪些令牌(符号)被传递到 FOR 迭代。可以分配额外变量。如果最后一个字符是 *,则额外的变量接收行中剩余的所有文本。例如 tokens=2,3* 会将第二个和第三个符号赋给两个变量,剩下的赋给第三个变量。
  • usebackq:用于处理文件名或路径中含有空格的情况。不使用 usebackq 时:(file) 表示文件,不能加引号;双引号表示字符串;单引号表示命令。使用 usebackq 时:(file)("file") 都表示文件(允许带空格的文件名);单引号表示字符串;反引号表示命令。

file-set

:一个或多个文件名。每份文件被打开、读取、处理。处理过程包括读取文件、分成行、每行解析成零或多个令牌,然后用令牌的值调用 FOR 循环。默认情况下,/F 传递每个文件每一行的第一个空白分隔符号,跳过空行。

%i

:专门在 FOR 语句中说明,%j%k 通过 tokens= 选项说明。最多可指定 26 个符号(字母 a~z 或 A~Z)。

系统提供的范例:

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k

说明:分析 myfile.txt 的每一行,eol=; 忽略分号开头的行;tokens=2,3* 将第二、三个符号传给 FOR 程序体;delims= , 用逗号和/或空格作分隔符;%i 取第二个符号,%j 取第三个符号,%k 取剩余部分。

自己动手的几个例子:

1. 分析文件:

FOR /F "eol=; tokens=1,2* delims=,- " %%i in (d:\test.txt) do echo %%i %%j %%k

2. 分析字符串:

for /f "tokens=1,2,3* delims=-, " %%i in ("aa bb,cc-dd ee") do echo %%i %%j %%k %%l

3. 分析命令输出(枚举环境变量):

FOR /F "tokens=1* delims==" %%i IN ('set') DO @echo [%%i----%%j]

如果使用了 usebackq,结果完全相同:

1. 分析文件:

FOR /F "usebackq eol=; tokens=1,2* delims=,- " %%i in ("d:\test.txt") do echo %%i %%j %%k

2. 分析字符串:

for /f "usebackq tokens=1,2,3* delims=-, " %%i in ('aa bb,cc-dd ee') do echo %%i %%j %%k %%l

3. 分析命令输出:

FOR /F "usebackq tokens=1* delims==" %%i IN (`set`) DO @echo [%%i----%%j]

FOR 命令中的变量

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 输出格式的行

注意:使用 ~ 语法时,必须用一个有效的 FOR 变量名终止。选取类似 %I 的大写变量名比较易读。

以下是一个综合示例,可以直接保存为 BAT 文件运行,观察变量扩展的效果:

@echo off
echo ---显示 "dir c:\boot.ini /b /ah"
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 不扩展变量 %%i
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~fI %%~fi
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~dI %%~di
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~pI %%~pi
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~nI %%~ni
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~xI %%~xi
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~sI %%~si
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~aI %%~ai
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~tI %%~ti
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~zI %%~zi
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~$PATH:I %%~$PATH:i
echo ---以下显示组合修饰符---
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~dpI %%~dpi
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~nxI %%~nxi
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~fsI %%~fsI
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~dp$PATH:I %%~dp$PATH:i
for /f "delims==" %%i in ('dir c:\boot.ini /b /ah') do echo 扩展变量到~ftzaI %%~ftzai
echo.
echo ---显示 "dir C:\WINDOWS\system32\notepad.exe /b"
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 不扩展变量 %%i
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~fI %%~fi
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~dI %%~di
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~pI %%~pi
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~nI %%~ni
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~xI %%~xi
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~sI %%~si
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~aI %%~ai
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~tI %%~ti
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~zI %%~zi
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~$PATH:I %%~$PATH:i
echo ---以下显示组合修饰符---
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~dpI %%~dpi
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~nxI %%~nxi
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~fsI %%~fsI
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~dp$PATH:I %%~dp$PATH:i
for /f "delims==" %%i in ('dir C:\WINDOWS\system32\notepad.exe /b') do echo 扩展变量到~ftzaI %%~ftzai
Pause

关于 ~I 删除引号的规则

  • 若字符串首尾同时存在引号,则删除首尾的引号;
  • 若字符串尾不存在引号,则删除字符串首的引号;
  • 如果字符串中间存在引号,或者只在尾部存在引号,则不删除。

看一个测试:建立临时文件 temp.txt,内容如下

"1111
"2222"
3333"
"4444"44
"55"55"55

用下面的代码测试:

@echo off
echo ^"1111>temp.txt
echo "2222">>temp.txt
echo 3333^">>temp.txt
echo "4444"44>>temp.txt
echo ^"55"55"55>>temp.txt
FOR /F "delims=" %%i IN (temp.txt) DO echo %%~i
pause
del temp.txt

执行后 CMD 回显:

1111    '字符串前的引号被删除
2222    '首尾引号都被删除
3333"   '前无引号,后面引号保留
4444"44 '前面引号删除,中间引号保留
55"55"55 '前面引号删除,中间引号保留

%~fI 示例

FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~fi
pause

放在桌面执行,会显示 C:\Documents and Settings\Administrator\桌面\test.bat 这样的完整路径,而如果用 %%i 只显示文件名。

%~dI 示例

:只打印文件所在的盘符。

%~pI 示例

:只打印路径(不含文件名)。

%~nI 示例

:只打印文件名(不含扩展名)。

%~xI 示例

:只打印扩展名。

%~sI 示例

:打印短文件名路径。

%~aI

:打印文件属性。

%~tI

:打印文件日期/时间。

%~zI

:打印文件大小。

注意:上面的例子中 "delims==" 可以改为 "delims="(不要分隔符)。

%~$PATH:I 示例

@echo off
FOR /F "delims=" %%i IN ("notepad.exe") DO echo %%~$PATH:i
pause

这条命令会在 PATH 环境变量指定的目录中搜索 notepad.exe,如果找到则打印其绝对路径,否则打印空字符串或错误信息。注意:这里的文件名需要用双引号括起来,并且不能使用中文字符的引号。