delims=
\,\,它的含义是:以逗号作为被处理的字符串的分隔符号。
如果没有指定\符号列表\这个开关,那么,for /f 语句默认以空格键或跳格键作为分隔符号。如果\,等号后为空,则不会分割。但是空白行将被忽略。
for /f 语句默认只提取第一节的符串。 [code5] @echo off
for /f \,\pause [code6] @echo off
for /f \,\pause
定点提取:tokens=
tokens= 后面一般跟的是数字,如 tokens=2,也可以跟多个,但是每个数字之间用逗号分隔,如 tokens=3,5,8,它们的含义分别是:提取第2节字符串、提取第3、第5和第8节字符串。tokens=1,2,3,4,5 可以简写为 tokens=1-5 。 [code7] @echo off
for /f \, tokens=2,5\pause
如果 tokens= 后面指定了多个数字,如果形式变量为%%i,那么,第一个数字指代的内容用第一个形式变量%%i来接收,第二个数字指代的内容用第二个形式变量%%j来接收,形式变量遵循字母的排序。
[code8] @echo off
for /f \, tokens=1,*\pause
文本:尺有所短,寸有所长,学好批处理没商量,考虑问题复杂化,解决问题简洁化。
运行结果:尺有所短 寸有所长,学好批处理没商量,考虑问题复杂化,解决问
题简洁化。
tokens=后面所接的星号具备这样的功能:字符串从左往右被切分成紧跟在*之前的数值所表示的节数之后,字符串的其余部分保持不变,整体被*所表示的一个变量接收。即:第一节字符串被切分完之后,其余部分字符串不做任何切分,整体作为第二节字符串。tokens=1,*可写为tokens=1*
跳过无关内容,直奔主题:skip=n
[code9 @echo off
for /f \pause
这段代码将跳过头两行内容,从第3行起显示test.txt中的信息。
忽略以指定字符打头的行:eol=
[code10] @echo off
for /f \pause
结果,那些以分号打头的行没有显示出来。eol= 的准确含义是:忽略以指定字符打头的行(只能忽略一个)。for /f 语句是默认忽略以分号打头的行内容的。
如何决定该使用 for /f 的哪种句式?(兼谈usebackq的使用)
1、for /f %%i in (文件名) do (??) 2、for /f %%i in ('命令语句') do (??) 3、for /f %%i in (\字符串\??)
为了兼容文件名中所带的空格或&,当路径中含有特殊字符的时候: 4、for /f \文件名\??) 5、for /f \命令语句`) do (??)
后引号`(键盘左上角esc键下面的那个按键,与~在同一键位上)。 6、for /f \字符串') do (??)
计数循环:for /l
for /l 语句的完整格式是这样的:for /l %%i in (x,y,z) do (??),在这个语句中,x、y和z都只能取整数,正负皆可,x指代起始值,y指代步长,z为终止值,具体含义为:从x开始计数,以y为步长,直至最接近z的那个整数值为止,这之间有多少个数,do后的语句就执行多少次。for /l 会将参数中不为有效数字的项和缺失的项理解为 0,典型例子为 for /l %%a in () do echo 无限循环
[code11]
for /l %%i in (1,2,10) do echo bathome
在以上的代码中,初始值是1,步长为2,终止值为10,表明计数从1开始,每隔2个数计算一次,直至最接近10的那个整数,罗列出来,就是1,3,5,7,9,再下一个就是11,超过10了,不再计算在内,所以,do后的语句只执行5次,将连续显示5个bathome。
实际上,x,y和z的值可正可负,甚至为0,限制非常宽松: 1、步长y的值不能为0;
2、当步长y的值为正整数时,终止值z不能小于初始值x; 3、当步长y的值为负整数的时候,终止值z不能大于初始值x。
换而言之,必须保证in和do之间能取到一个有效的数组序列。
46.setlocal enabledelayedexpansion 例1:
@echo off & setlocal EnableDelayedExpansion
for /f \set n=%%i set n=!n:ld.=t! set n=!n:o w= S! set n=!n:He=Wi! echo !n! )
pause
执行后会显示“Will Sort”字符串。
当CMD读取for语句时,其后用一对圆括号闭合的所有语句将一同读取,并完成必要的预处理工作,这其中就包括环境变量的扩展,所以在for中的所有语句
执行之前,所有的环境变量都已经被替换为for之前所设定的值,从而成为一个字符串常量,而不再是变量。
而为了能够在for语句内部感知环境变量的动态变化,CMD设计了延迟的环境变量扩展特性,也就是说,当CMD读取了一条完整的语句之后,它不会立即执行变量的扩展行为,而会在某个单条语句执行之前再进行扩展,也就是说,这个扩展行为被“延迟”了。
总的来说是,在没有启用变量延迟的情况下,凡是在括号内(即do里面)的变量,在执行for语句之前,就已经被替换成for语句之前其它命令对该变量所赋予的值。
例2: @echo off
for /f \set n=%%i
set n=%n:ld.=t% set n=%n:o w= S% set n=%n:He=Wi% echo %n% )
pause
执行结果是显示“ECHO 处于关闭状态”。
第一句set n=%%i能正常执行并达到它的目的,因为它只是单纯地将%%i的值赋予给变量n,所以没有任何问题。其它几句属这样情况:早在for语句执行前,CMD就急不切待地将这几句里面的所有变量n一同执行替换行为,替换为for之前,其它命令对n所设置的值,从而使n变成一个常量。但在本例中,for语句之前只有@echo off这句,并没有其它命令对n作过任何赋值行为,所以在for之前,变量n的值为空值。即是说,set n=%n:ld.=t% 这句里面的变量n,在CMD读取(注意是读取不是执行)完整个for语句后(这时还未轮到set执行自己的任务),就立刻被替换为一个空值,一个空值里面没有任何东西,所以就不存在一字符替换另一字符这种说法。
例3:这是个错误的例子 @echo off
set mm=girl&echo %mm% pause
执行后依然显示“ECHO 处于关闭状态”。
原因是没有启用延迟,而且在set mm=girl&echo %mm%语句前没有其它命令对mm进行赋值。这时当CMD执行set mm=girl&echo %mm%语句前,就已经急不切待地把变量mm的值替换了,而又因为前面没给mm赋值,所以mm被替换为空值,变成常量。等到echo命令执行时,它其实是echo一个不会变化的常量,本例中即是空值。
总的来说是,如果不启用变量延迟,在本例中,echo是不会理会也不会知道,
它前面(指同一行语句)是否有其它命令给mm赋值。它只会从set mm=girl&echo %mm%这句以上的语句中获取它所要显示的变量的内容,也就是说,上一行或上几行的命令将mm设置成什么值,echo命令就显示什么值。
47.call set 变量嵌套变量
例:
@echo off
set a=1&set b1=10 call,echo %%b%a%%% pause>nul
call 这里实际是对命令行进行重新组织扩展,先扩展%%b%a%%%里面的%a%,使%a%变成a的值1,再用cal来扩展±%。 也可以用变量延迟来实现,方法如下: @echo off
set /a a=1,b1=10
Setlocal EnableDelayedExpansion echo:!b%a%! pause
call 在这里的用法实际是变量延迟的一种快捷方式,变量延迟一般用在for的循环体里面。
call,%%b%a%%% 这里的逗号实际是一个分隔符,和空格一样,还有很多分隔符可用,比如上例中的 echo:!b%a%! ,当然并不是所有的命令都可以这样用,看情况而定。 Q:为什么将连接两个set语句的&两边加个空格,即:set a=1 & set b1=10,运行结果A:为:ECHO 处于关闭状态?
加了空格,变量a的值就是1加上一个空格了,而不是原来单独的一个1。
附:转义字符%
为什么变量转义字符%%会只显示一个%
用ECHO命令显示“ %~dpI”问题,为什么编写批处理的时候必须用ECHO %%~dpI语句才能显示出“ %~dpI”这个呢?为什么用回显命令执行的时候只显示一个呢?
1、%是个ESCAPE字符,通常将之译为转义字符,但也有更形象的译名脱逸字符、逃逸字符等。也就是说%不仅仅将与其相关的特定字符串转义并替换为