循环 for

1. 如果批处理不具备批量处理的功能,那么它就徒有虚名了。而命令 for ,在某种意义上彻底体现出了批处理的强大快捷省事批量的作用。在看过 for/? 后,可以归纳出 for 大致可以分三种常用的类型(或者叫使用方法)。从针对的循环目标来看,它们分别是针对于文件、数字、以及文字。

2. for %i in (*.*) do @echo %i 。这就是 for 的一般使用格式。注意到其中的浅靛色文字 for 、in 和 do ,是 for 的固定用法。其内容可以理解为:在某一范围内(in),对于其中的某一文件来说(for),做如下的处理(do)。而 for %i in (*.*) do @echo %i 就是在当前工作目录的所有文件中(in (*.*)),对于其中的某一文件(for %i),做出显示其名称的处理(do @echo %i)。变量 i 仅在当前循环语句 for 里起作用,%i 表示其值。

注意:以上是直接在命令提示符里以命令的形式表达出来的写法;在批处理文件中应使用双百分号 %% 代替单百分比号 % ,就像:%%i。

批量修改文件名是其比较有用的典例之一。看看下面的批处理

:::::::批量修改文件名.bat:::::::

@echo off

setlocal EnableDelayedExpansion

set /a num=1

for %%i in (D:\test\*.txt) do (

ren "%%i" !num!.txt

set /a num+=1

)

::::::::::::::::::::::::::::::::

使用了 setlocal EnableDelayedExpansion 后,可以让 for 或 if 后面的执行语句中变量的值随其变化而不断更新(所以后面使用了 !num! 而不是 %num%)。整个批处理的处理过程就是对 D:\test\*.txt 中的所有文本文件进行批量改名,文件名从 1.txt 开始依次为 2.txt 、3.txt ……。

注意:请确保循环语句 in 路径中的文件不是重要的文件,因为改名后将无法使用撤消,如果像我一样不小心把重要文件误改名的话就又要 orz 了一次。

以上批处理是固定了文件的路径以及文件后缀名。为了增加该批处理的功能,我们可以让用户自己选择要进行改名的文件所在路径,以及选择所进行文件修改的后缀名。当然,有些朋友还希望有给文件批量加上前缀(比如:前缀1.txt 前缀2.txt 等等)。(关于 批量改文件名.bat 在第六章中还有进一步的修改)

::::::::批量改文件名.bat::::::::

@echo off

setlocal EnableDelayedExpansion

set /p zpath=请输入目标文件所在的路径:

set /p prefix=请输入文件名前缀(不能包含以下字符\/:*?"<>|):

set /p ext=请输入文件的扩展名(例如 .txt):

set /a num=1

for %%i in (%zpath%\*%ext%) do (

ren "%%i" "%prefix%!num!.%ext%"

set /a num+=1

)

::::::::::::::::::::::::::::::::

3.也许大家注意到了,上面 for 的用法仅仅是针对多个文件来进行循环重复操作的。如果想对一系列有规律的数字进行循环,或是在一定的次数内对某个操作进行循环重复的执行,使用 for 也能够实现。/l 是可以跟在 for 后面的重要参数之一。比如:for /l %i in (5,3,16) do echo %i ,可以让数值型的变量 i 依次成为:5、8、11、14 。正如 in 里所描述的规律 (5,3,16) 一样,从 5 开始,每次增加 3 ,直到 16为止。同样,我们还可以试一下 for /l %i in (19,-4,3) do echo %i ,这次 i 是递减的规律。很明显,结果将依次显示为:19、15、11、7、3 。

 

::::::::::圆圈方阵.bat::::::::::

@echo off

setlocal EnableDelayedExpansion

 

set var=○

for /l %%i in (1,1,7) do set var=%var%!var!

:: 此时变量 var 已经变成一行连续的8个圆圈了

 

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

echo 这是第 %%i 份>输出结果%%i.txt

for /l %%j in (1,1,8) do echo %var%>>输出结果%%i.txt

)

echo 8 X 8 的 ○ 矩阵已经画好,并保存到8份文本文件里了

pause

::::::::::::::::::::::::::::::::

注意:%%i ,在批处理文件中需要用连续的两个百分号 %% 来描述循环变量 i ,而不是一个。

注意:i 与 j ,在循环里面再套循环时,前一个循环变量 i 在没有释放之前,不应该让第二个循环变量的名称与 i 重复。

 

4.for 也可以对指定范围内的文字进行循。for 后面跟参数 /f ,/f 后面跟选项,所指定的范围 in 里可以是一个文件里的文字,可以是一个字符串,也可以是一条命令的输出结果。我们首先以一个文件里的文字作为循环对象,循环时,每一行将被循环一次。

::::::::::文字筛选.txt::::::::::

@echo off

echo 测试 文字筛选.txt 里每一行的首单词

for /f %%i in (文字筛选.txt) do echo %%i

pause

 

echo.

echo skip=2 表示前两行被跳过

for /f "skip=2" %%i in (文字筛选.txt) do echo %%i

pause

 

echo.

echo tokens=2,4-6 表示提取每行的第2个、以及第4到6个单词

for /f "skip=2 tokens=2,4-6" %%i in (文字筛选.txt) do echo %%i, %%j, %%k, %%l.

pause

 

echo.

echo eol=N 表示当此行的首字母为 N 时,就忽略该行

for /f "eol=N skip=2 tokens=2,4-6" %%i in (文字筛选.txt) do echo %%i, %%j, %%k, %%l.

pause

 

echo.

echo delims=e 表示不再以空格区分每个词,而是以字母 e 作为间隔

for /f "eol=N skip=2 tokens=2,4-6 delims=e" %%i in (文字筛选.txt) do echo %%i, %%j, %%k, %%l.

pause

 

echo.

echo usebackq 表示双引号里的东西是文件名而不是字符串

for /f "usebackq eol=N skip=2 tokens=2,4-6 delims=e" %%i in ("文字筛选.txt") do echo %%i, %%j, %%k, %%l.

pause

::::::::::::::::::::::::::::::::

作为测试,可以在上述批处理文件的同一路径下创建一个用于测试的文本文件 文字筛选.txt ,其内容为:

Hello there!

This text is an example of test for the batch file 文字筛选.bat.

Notice the first letter in this line, N.

If the eol charactor was set to be letter N.

The third line will not be considered by the batch.

 

5. ESCAPE字符 % ,通常被译为转义字符,但也有更形象的译名脱逸字符、逃逸字符等。也就是说 % 不仅仅将与其相关的特定字符串转义并替换为特定字符串,而且自身也会被“脱逸”。而且类似于C语言中的转义字符 \ ,双%会转义并脱逸为单百分号 % ,四%则脱为双百分号 %% 。[3]

 

注意下面这个批处理中的双百分号 %% 的用法

::::::::::::::::::::::::::::::::

@echo off

set Text=Hello world!

for /l %%i IN (0,1,11) do call echo %%Text:~%%i,1%%

pause