set var=Tom
if %var%==Tom echo It works
if %var%==Jerry echo We will never see this
如果变量 var 的值为 Tom Hanks ,即中间含有空格之类的特殊符号,那么我们在使用 if 时,就得为字符串加上双引号,就像 if "%var%"=="Tom Hanks" echo It works (注意,给字符串加上双引号后,在进行判断的时候会连双引号一起考虑进去。所以,为了使两边的对比均衡,所以一定要在 == 两边的两个字符串上同时都加双引号)。这里也体现了批处理程序语言格式的多样性(如果您熟悉 C 语言格式的话,就知道一串字符总是要被双引号引起来)。不过为了方便记忆,我们在使用 if 的时候,不妨总是在字符串上使用双引号,这样既好阅读,又不容易引起歧异。
@echo off
echo 您希望字体的颜色是红色还是绿色?
:RETRY
set /p choice=请输入您的选择,R 或者 G :
if "%choice%"=="R" goto R
if "%choice%"=="r" goto R
if "%choice%"=="G" goto G
if "%choice%"=="g" goto G
goto RETRY
:R
color c
echo 您选择了红色字体
pause
exit
:G
color a
echo 您选择了绿色字体
pause
exit
::::::::::::::::::::::::::::::::
上面的例子能很好地说明了 if 与 goto 的结合使用带来的实用效果。其中,在使用 if 进行判断变量 choice 的值是否为字母 R 或 G 时,分别对其大小写都进行了判断。其实您还可以使用 if 的参数 /i ,就像 if /i "%choice%"=="r" ,这样在进行比较的时候就不区分大小写了。
:::::::::else的用法.bat:::::::::
@echo off
if "%TIME:~0,2%" lss "12" (
echo 现在是上午
) else (
echo 现在是下午
)
pause
::::::::::::::::::::::::::::::::
其中,变量 TIME 是动态环境变量之一,表示当前时间(在 set/? 中有介绍)。%TIME:~0,2% 的含义还没忘记吧,意思是取变量 TIME 的前两个字符(忘记的朋友请参阅上一篇[赋值 调用 参数])。lss 是 if 命令扩展用法,表示 小于 的意思。此外,还有等于、不等于、大于、大于等于、小于等于 的缩写,详细信息可以在 if/? 中获得。因此,对于上述批处理的理解就是:如果当前时间(前两位表示小时)小于12(点)的话,那么将显示输出“现在是上午”,否则就显示为“现在是下午”。另外:这里的大小比较判断只是对其ASCII符的大小比较,并不是真正的数值型变量的比较,稍后下文会有关于数值型变量比较的介绍。
:::::::::else的用法.bat:::::::::
@echo off
if "%TIME:~0,2%" lss "12" (
if "%TIME:~0,2%" lss " 6" (
echo 现在是凌晨
) else (
echo 现在是上午
)
) else (
if "%TIME:~0,2%" lss "18" (
echo 现在是下午
) else (
echo 现在是晚上
)
)
pause
::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::
@echo off
set /a num=5
if %num% == 5 (
echo 变量 num 等于 5
)
if not %num% == 4 (
echo 变量 num 不等于 4
)
set /a num = ( %num% + 3 ) * 2
:: 变量 num 加3并乘2后再赋给变量 num 自身
if %num% == 16 (
echo 经过运算后,现在变量 num 等于16
)
if not %num% == 16 (
echo 此时的变量 num 不会不等于 16 ,因此这一句不会显示了
)
pause
::::::::::::::::::::::::::::::::
::::::::延迟变量扩充.bat::::::::
@echo off
setlocal EnableDelayedExpansion
set /a num=5
if %num% == 5 (
set /a num*=3
echo 在 if 语句之前,变量 num 等于 %num%
echo 但变量 num 在经过运算后,且由于延迟变量扩充被启用,变量 num 等于 !num!
)
echo 但最终变量 num 还是等于 %num%
pause
::::::::::::::::::::::::::::::::
if 条件下的两行 echo 在输出变量值的时候用到的符号不一样,一个是用百分号 % 包括起来的,另一个用的却是惊叹号 ! 。虽然在显示 %num% 之前已经使变量 num 的数值乘了3倍,但是由于没有延迟变量的扩充,使得 %num% 的结果仍然是 5 。但用 !num! 显示出的值已经变为 15 了。注意到批处理中的 setlocal EnableDelayedExpansion (setlocal/? 查看相关信息),这表示开启延迟变量扩充。此时的 !num! 才有意义。不然 !num! 将无法被识别,因为在默认情况下,延迟变量扩充是被停用的。
if exist "D:\test my folder\a.txt" (
del "D:\test my folder\a.txt"
) else (
echo 您所要删除的文件不存在
)
在对文件进行操作之前进行判断其是否存在很有意义,这使得代码更加健壮。
注意:以上是直接在命令提示符里以命令的形式表达出来的写法;在批处理文件中应使用双百分号 %% 代替单百分比号 % ,就像:%%i。关于它们之间的区别我研究了好半天才分清楚 orz [具体请参阅后文第4.2.5节]。
:::::::批量修改文件名.bat:::::::
@echo off
setlocal EnableDelayedExpansion
set /a num=1
for %%i in (D:\test\*.txt) do (
ren "%%i" !num!.txt
set /a num+=1
)
::::::::::::::::::::::::::::::::
这个批处理并不难理解。就像第4.1.5节所说的:使用了 setlocal EnableDelayedExpansion 后,可以让 for 或 if 后面的执行语句中变量的值随其变化而不断更新(所以后面使用了 !num! 而不是 %num%)。整个批处理的处理过程就是对 D:\test\*.txt 中的所有文本文件进行批量改名,文件名从 1.txt 开始依次为 2.txt 、3.txt ……。
注意:请确保循环语句 in 路径中的文件不是重要的文件,因为改名后将无法使用撤消,如果像我一样不小心把重要文件误改名的话就又要 orz 了一次。
::::::::批量改文件名.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
)
::::::::::::::::::::::::::::::::
::::::::::圆圈方阵.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 ,而不是一个。
注意:%var% 与 !var! ,它们的用法与区别,在第4.1.5节中有解释。
注意:i 与 j ,在循环里面再套循环时,前一个循环变量 i 在没有释放之前,不应该让第二个循环变量的名称与 i 重复。
注意:> 与 >> ,同样是向某设备里输出,但却有区别,请参阅第2.2节。
::::::::::文字筛选.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.
::::::::::::::::::::::::::::::::
@echo off
set Text=Hello world!
for /l %%i IN (0,1,11) do call echo %%Text:~%%i,1%%
pause
::::::::::::::::::::::::::::::::