Fork me on GitHub

for

-------siwuxie095

   

   

   

   

for 语句很强大,配合 ifcallgoto 等流程控制语句,更是可以实现

脚本复杂的自动化、智能化操作,离开了 for 语句,很多事情都办不了

   

   

但是 for 命令是如此之复杂,学习 for 语句很艰难,假如想通过

帮助命令里的信息来学习 for 语句,会让人感到绝望!能否熟练

充分使用 for 命令,是高手与低手的分水岭,下面将 for 语句彻

底拆解!

   

首先是帮助信息:

   

   

   

   

   

   

FOR

对一组文件中的每一个文件执行某个特定命令

   

   

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

   

   

更详细的语法:

FOR [-d | -r | -l | -f] %%variable IN (set) DO command [command-parameters]

   

中文"翻译":

FOR [-d | -r | -l | -f] %%变量名 IN (相关文件或命令) DO [执行命令]

   

这里用 %%,两个百分号是批处理文本中书写的格式,如果是用户在

命令行输入的形式,只需一个 %

   

注解:

for 有四个参数: /d /r /l /f

%%变量名:变量名可以是单个的大小写字母(区分大小写),for 会把

(set) 读取到的每个值按顺序赋值给它

in: 命令格式,默认即可

(相关文件或命令) for 把这里的值读取后赋值给变量 %%variable

do: 命令格式,默认即可

执行命令 对每个变量的值要执行的操作,当然也可以没有任何操作,这个看

实际需要。例如利用 for 循环来延迟程序,就不需要 for 执行任何操作,只需

要不断循环即可

   

   

   

参数详解:

   

for 没有任何开关的情况:

   

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

   

这条命令的变量 %%i 取值 *,而不是取具体值,表示特殊

含义,即显示当前目录下,所有非文件夹的文件名字(包

.rar .jpg .exe .bat .sys 等所有非文件夹)

   

@echo off

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

pause

   

sublime中:

   

   

运行一览:当前目录下只有 test.bat 本身这一个文件(非文件夹)

   

   

   

%%i 取具体的值,即表示分别取列出来的具体的值:

   

for %%i in (a, b c,d,e) do echo %%i

   

@echo off

for %%i in (a, b c,d;e) do echo %%i

pause

   

sublime中:

   

   

运行一览:

   

   

   

显然:空格、逗号和分号都可以作为分隔符。一般情况下,都用

逗号作为分隔符,尤其在数据是数字的情况下更具有可读性。

   

   

利用这个特点可以将变量 %%i 取一些不连续的值。

例如要将变量分别取值为 1、1945、1949、2008、2012 五个值,

由于变量之间不是等差数列关系,用 for /l %%i in () do () 循环的

形式无法达到目的。

   

这样写即可:

for %%i in (1,1945,1949,2008,2012) do echo %%i

   

   

输出字母表:

因为批处理不可以直接转换为 ASCII 值,所以比 C 语

言麻烦。在批处理里,用 for 输出字母表最简洁

@echo off

for %%i 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 echo %%i

pause

   

或:

   

@echo off

set var=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

for %%i in (%var%) do echo %%i

pause

   

   

   

   

/d

只搜索当前目录下的目录(也就是文件夹 ,不包括子目录)

注意:/d 无法搜索到隐藏的文件夹

   

语法:

for /d %%variable in (set) do command [command-parameters]

   

搜索 set(可以包含通配符 * ?)里的文件夹后执行指定的

Command。用于目录搜索,不会搜索文件。

   

通配符 * 的区别:

* 表示任意 n 个字符,用一个 * 符号足以。而 表示任意一个字符,

当要表达"不多于 k 个字符的文件夹",就要写上 k,对于文件

夹命名中的中文(任意个),算作 0 个字符

   

例如:??? 三个问号,不仅代表有三个字母的文件夹,还包括一个

字母的文件夹和两个字母的文件夹,都会被搜索出来

   

如:

@echo off

for /d %%i in (F:\*) do echo %%i

pause

   

sublime中:

   

   

运行一览:

   

   

   

   

/d 不能显示文件名字,只能显示目录。说白了就是显示

该目录下的所有文件夹名字

   

再如:

"program files" 含有空格,必须用双引号,否则出错

@echo off

for /d %%i in (C:\"program files"\*) do echo %%i

pause

   

sublime中:

   

   

运行一览:将 C:\program files 里面的所有文件夹都显示出来

   

   

   

   

再如:

@echo off

for /d %%i in (???) do echo %%i

pause

   

sublime中:

   

   

运行一览:把这个批处理程序放在哪里运行,

程序会把当前路径下名字只有 1~3 个字母的

文件夹显示出来 ,没有就不显示

(这是在桌面的运行结果)

   

   

   

   

再如:指定搜索路径

@echo off

for /d %%i in (C:\windows\????) do echo %%i

pause

   

sublime中:

   

   

运行一览:

   

   

   

   

for /d 不能匹配带隐藏属性的文件夹,在灵活性上不及 for /f dir 的组合;

当 "元素集合"中不包含任何通配符时,完全是 "for %%i in (元素集合) do …"

语句的翻版,但又稍显复杂。感觉 for /d 很鸡肋

   

   

   

   

   

   

/r

只搜索目录中(包括子目录和子目录的子目录,也就是目录树)的所

有文件。这个和 /d 作用互补

   

语法格式:

FOR /R [[drive:]path] %%variable IN (set) DO command [command-parameters]

   

如果在 /r 后没有指定目录,则使用当前目录。如果 set 仅为一个单点(.)字符,

则枚举该目录树。

例如:for /r C:\windows %%i in (.) do echo %%i 枚举 C:\windows 目录树的

所有文件。

   

/r 可以把当前或指定路径下的文件名字全部读取,注意是文件名

字。

   

注意两点:

a、set 中的文件名如果含有通配符( ?* ),则列举 /r 参数指定的目录

及其下面的所用子目录中的与 set 相符合的所有文件,无相符文件的目录

则不列举。

b、相反,如果 set 中为具体文件名,不含通配符,则枚举该目录树(即

列举该目录及其下面的所有子目录),而不管 set 中的指定文件是否存在。

这与前面所说的单点( . )枚举目录是一个道理,单点代表当前目录,也可

视为一个文件

   

   

如:将 C盘根目录及其子目录下的所有 exe 文件显示出来

@echo off

for /r c:\ %%i in (*.exe) do (echo %%i & pause > nul)

pause

   

sublime中:

   

   

   

   

再如:没有指定搜索路径,则默认

当前目录为搜索路径

@echo off

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

pause

   

   

再如:

@echo off

for /r C:\ %%i in (bootres.dll) do echo %%i

pause

   

运行后会列举C盘所有目录,且每个目录都会显示 bootres.dll,

但实际上并不是真的存在 bootres.dll,只是计算机在搜索所有

目录时伴随回显罢了

   

若要只列举 bootres.dll 存在的目录:

@echo off

for /r C:\ %%i in (bootres.dll) do if exist %%i echo %%i

pause

   

运行一览:win 10下存在 bootres.dll,其他系统未知

   

   

   

   

   

   

若要对获取到的路径做进一步处理,则需要把 dir 语句放入 for /f 语句

中进行分析,写成 for /f %%i in ('dir /ad /b /s') do … 的形式;

   

由于 for /r 语句是边列举路径边进行处理,所以,在处理大量路径时,

前期不会感到有停顿,而 for /f 语句则需要等到 dir /ad /b /s 语句把

所有路径都列举完之后,再读入内存进行处理,所以,在处理大量路径

时,前期会感到有明显的停顿

   

   

当列举目录时,for /r dir /ad /b /s 的效果非常类似,当要获取

目录路径并做进一步处理的时候,两者之间,该如何选择?

   

a、for /r

优点:

只通过 1 条语句就可以同时实现获取目录路径

和处理目录路径 2个操作;

遍历文件夹时,边列举边处理,获取到一条路径

就处理一条路径,内存占用小,处理大量路径时不会

产生停顿感;

   

缺点:

不能获取到带隐藏属性的目录,产生遗漏;

不能获取带指定属性的目录;

   

   

bdir /ad /b /s

优点:

能一次性获取带任意属性的目录,不会产生遗漏;

能通过指定不同的参数获取带任意属性的目录,更具灵活性;

   

缺点:

dir /ad /b /s 仅能获取到目录路径,若要实现进一步的处理,

还需要嵌入 for /f 语句中才能实现,写法不够简洁;

嵌入 for /f 语句之后,需要写成 for /f "delims=" %%i in

('dir /ad /b /s') do … 的格式,受 for /f 语句运行机制的制约,

需要先列举完所有的路径放入内存之后,才能对每一条路径做

进一步的处理,处理大量路径时,内存占用量偏大,并且在前

期会产生明显的停顿感,用户体验度不够好;

   

   

   

   

综上,可做出如下选择:

a、若仅仅是为了获取某文件夹及其所有子文件夹的路径的话,

选择 dir /ad /b /s 语句;

b、若需要过滤带隐藏属性的文件夹,for /rdir 语句都可以

实现,但 for /r 内存占用小,处理速度快,是上上之选;

c、若需要获取所有文件夹,则除了 dir /ad /b /s 外,别无选择,

因为 for /r 语句会遗漏带隐藏属性的文件夹

   

   

   

   

   

/l

语法格式:

FOR /L %%variable IN (start,step,end) DO command [command-parameters]

   

start 开始,以 step 为步长,直至最接近 end 那个整数为止,中间有

多少个整数,do 后面就执行多少次

   

(1,1,5)将产生序列 12345,5 次重复,并依次将序列赋值到变量 %%i

(5,-1,1)将产生 54321 序列,5 次重复,并依次将序列赋值到变量 %%i

   

常用于循环结构,对于 in 后面括号里的三个变量 ,逗号隔开

改为空格隔开也可,不过不建议用空格隔开

   

如:竖着显示 12345

@echo off

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

pause

   

如:打开 5 cmd 窗口

@echo off

for /l %%i in (1,1,5) do start cmd

pause

   

   

注意:在循环里,不能改变循环变量的值!对循环上下限变量

允许计算,但不会影响循环次数

   

如:循环变量 %%i 的值不变

@echo off

setlocal enabledelayedexpansion

for /l %%i in (1,1,10) do (

set %%i+=10

echo %%i

)

pause

   

   

如:上下限的值变了,循环次数不变

@echo off

setlocal enabledelayedexpansion

set /a min=1,max=10

for /l %%i in (!min!,1,!max!) do (

echo min=!min! max=!max!

set /a min+=1

set /a max*=2

)

pause

   

   

for 里的循环变量 %%i 和参数 %0 - %9,就代表它是变量,

在引用时,不可以再对其增加变量符号,即%%%i%!%%i!

%%1%!%1! 等形式都不可以

   

   

循环结构的选择 for 还是 goto

   

当循环次数确定时,首选 for /l 语句,代码简单明了,也可

使用 goto 语句但不推荐;

当循环次数不确定时,用 goto 语句将是唯一的选择,此时

需要用 if 之类的条件语句来判断何时结束 goto 跳转

   

   

无限循环:

for /l %%i in () do echo Hello

   

@echo off

for /l %%i in () do echo Hello

pause

   

   

   

【made by siwuxie095】

   

posted on 2017-02-06 16:51  siwuxie095  阅读(515)  评论(0编辑  收藏  举报

导航