终极dos批处理循环命令详解
格式:FOR [参数] %%变量名 IN (相关文件或命令) DO 执行的命令
做用:对一个或一组文件,字符串或命令结果中的每个对象执行特定命令,达到咱们想要的结果。
注意:在批处理文件中使用 FOR 命令时,指定变量请使用 %%variable,而不要用 %variable。变量名称是区分大小写的,因此 %i 不一样于 %I.
关于:for命令能够带参数或不带参数,带参数时支持如下参数:/d /l /r /f
下面分别解释一下dom
===
零:无参数时:
---
FOR %variable IN (set) DO command [command-parameters]
%variable 指定一个单一字母可替换的参数。
(set) 指定一个或一组文件。可使用通配符。
command 指定对每一个文件执行的命令。
command-parameters
为特定命令指定参数或命令行开关。ide
TTT示例:
for %%i in (t*.*) do echo %%i --显示当前目录下与t*.*相匹配的文件(只显示文件名,不显示路径)
for %%i in (d:\mydocuments\*.doc) do @echo %%i --显示d:\mydocuments\目录下与*.doc相匹配的文件
===
1、参数 /d (参数只能显示当前目录下的目录名字)
---
格式:FOR /D %variable IN (set) DO command [command-parameters]
这个参数主要用于目录搜索,不会搜索文件,/D 参数只能显示当前目录下的目录名字。(TTT特别说明:只会搜索指定目录下的目录,不会搜索再下一级的目录。)oop
TTT示例:
for /d %%i in (c:\*) do echo %%i --显示c盘根目录下的全部目录
for /d %%i in (???) do echo %%i --显示当前目录下名字只有1-3个字母的目录测试
===
2、参数 /R (搜索指定路径及全部子目录中与set相符合的全部文件)
---
格式:FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
此命令会搜索指定路径及全部子目录中与set相符合的全部文件,注意是指定路径及全部子目录。ui
一、set中的文件名若是含有通配符(?或*),则列举/R参数指定的目录及其下面的所用子目录中与set相符合的全部文件,无相符文件的目录则不列举。
二、若是set中为具体文件名,不含通配符,则枚举该目录树(即列举该目录及其下面的全部子目录)(并在后面加上具体的文件名),而无论set中的指定文件是否存在。
例:for /r c:\ %%i in (*.exe) do echo %%i --把C盘根目录,和每一个目录的子目录下面所有的EXE文件都列出来了!!!!idea
TTT示例:
for /r c:\ %%i in (boot.ini) do echo %%i --枚举了c盘全部目录
for /r d:\backup %%i in (1) do echo %%i --枚举d\backup目录
for /r c:\ %%i in (boot.ini) do if exist %%i echo %%i --很好的搜索命令,列举boot.ini存在的目录spa
===
3、参数 /L (该集表示以增量形式从开始到结束的一个数字序列。可使用负的 Step)
---
格式:FOR /L %variable IN (start,step,end) DO command [command-parameters]
该集表示以增量形式从开始到结束的一个数字序列。可使用负的 Step命令行
TTT示例:
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个文件夹设计
4、参数 /F (使用文件解析来处理命令输出、字符串及文件内容。)
---
这个参数是最难的,参数又多,先简单的解释一下:for命令带这个参数能够分析文件内容,字符串内容或某一命令输出的结果,并经过设置option得咱们想要的结果。
如下是某高手的解释,感受有点太专业了,自认为不太容易理解,也列一下:
[迭代及文件解析--使用文件解析来处理命令输出、字符串及文件内容。使用迭代变量定义要检查的内容或字符串,并使用各类options选项进一步修改解析方式。使用options令牌选项指定哪些令牌应该做为迭代变量传递。
请注意:在没有使用令牌选项时,/F 将只检查第一个令牌。文件解析过程包括读取输出、字符串或文件内容,将其分红独立的文本行以及再将每行解析成零个或更多个令牌。而后经过设置为令牌的迭代变量值,调用 for 循环。
默认状况下,/F 传递每一个文件每一行的第一个空白分隔符号。跳过空行。]
+++
格式:
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]rest
或者,若是有 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]
TTT说明:以上是WinXP系统中的帮助内容,你能够注意到,二者彻底相同,这实际上是系统的错误,第二段“若是有 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] --(`command`中的引号为反引号,是键盘上数字1左面的那个键)
+++
(TTT说明:下面是详细的解释,大部分是系统中的帮助内容,也有些错误(怪不得for命令这么难学),已经被我纠正了。)
1) OPTION关键字详解:
eol=c:指一个行注释字符的结尾(就一个)。例如:eol=; --忽略以分号打头的那些行;
skip=n:指在文件开始时忽略的行数。例如:skip=2 --忽略2行;
delims=xxx:指分隔符集。这个替换了空格和跳格键的默认分隔符集。例如:[delims=, ] --指定用逗号,空格对字符串进行分隔。
tokens=x,y,m-n:指每行的哪个符号被传递到每一个迭代的 for 自己。这会致使额外变量名称的分配。m-n格式为一个范围。经过 nth 符号指定 mth。若是符号字符串中的最后一个字符是星号,那么额外的变量将在最后一个符号解析以后分配并接受行的保留文本。例如:tokens=2,3* --将每行中的第二个和第三个符号传递给 for 程序体;tokens=2,3* ... i% --将会把取到的第二个字符串赋给i%,第三个赋给j%,剩下的赋给k%。
关于usebackq,不一样版本的系统提示不一样的帮助,不过都有助于理解,因此都摘抄以下:
(1),usebackq:使用后引号(键盘上数字1左面的那个键`)。未使用参数usebackq时:file-set表示文件,不能加引号,因此 不能含有空格;加双引号表示字符串,即"string";加单引号表示执行命令,即'command'。使用参数usebackq时:file-set 和"file-set"都表示文件,当文件路径或名称中有空格时,就能够用双引号括起来;单引号表示字符串,即'string';后引号表示命令执行,即 `command`。(此段是WinXP系统中的帮助)
(2),usebackq:指定新语法已在下类状况中使用:在做为命令执行一个后引号的字符串;而且一个单引号字符为文字字符串命令;并容许在filenameset中使用双引号扩起文件名称。
以上两条结合着看,其实已经能够明白了,我再说明一下:
其实这个参数的目的就是为了处理带有空格的文件名。若是您要处理的文件名和路径中含有空格,若是直接使用,会提示找不到文件。若是你用双引号将文件名 和路径括起来。这时候将做为字符串处理,而不是做为文件了。为了应对这种状况,因此才增长了这个“usebackq”参数。若是使用了这个参数,对于括号 中的加双引号的集合,系统就能够认为是文件了;真正的字符串要加单引号;命令要加反引号。
2) file-set 为一个或多个文件名。继续到 file-set 中的下一个文件以前,每份文件都已被打开、读取并通过处理。处理包括读取文件,将其分红一行行的文字,而后将每行解析成零或更多的符号。而后用已找到的符 号字符串变量值调用 For 循环。以默认方式,/F 经过每一个文件的每一行中分开的第一个空白符号。跳过空白行。您可经过指定可选 "options"参数替代默认解析操做。这个带引号的字符串包括一个或多个指定不一样解析选项的关键字。
3) %i:专门在 for 语句中获得说明,%j 和 %k 是经过tokens= 选项专门获得说明的。您能够经过 tokens= 一行指定最多 26 个符号,只要不试图说明一个高于字母 'z' 或'Z' 的变量。请记住,FOR 变量是单一字母、分大小写和全局的;并且,同时不能有 52 个以上都在使用中。
(TTT补充说明:
通常在tokens后只指定第一个参数,如%%i或%%a,在后面使用第二个及两个以上的参数,自动按顺序往下排便可。如前面指定的是%%a,后面则 用%%b表明第二个结果,%%c表明第 三个结果。。。测试了一下tokens后指定多个变量名,没有测试成功,应该是不能够的。因此token后只能跟要使用的第一个变量名
若是使用的变量名超过了%z或%Z,就没法使用了,曾经觉得会循环过来:如%%z后可使用%%a或%%A,但经测试,这是不能够的。
如:for /f "tokens=1,2,3* delims=-, " %%y in ("aa bb,cc-dd ee") do echo %%y %%z %%A %%a --只会输出前两个字符串,后面的两个变量是无效的。)
+++
如下是系统提供的范例:
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 --这个 for 程序体的语句引用 %i 来取得取得的首个字符串(本例中为第二个符号),引用 %j 来取得第二个字符串(本例中为第三个符号)引用 %k来取得第三个符号后的全部剩余符号。
(TTT说明:上述例子和说明中明显的错误,%i应该换为%%i(帮助中有明确的说明:指定变量请使用 %%variable,而不要用 %variable,误导)
+++
TTT:下面列我作的几个例子:
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
%~fI - 将 %I 扩充到一个彻底合格的路径名
%~dI - 仅将 %I 扩充到一个驱动器号
%~pI - 仅将 %I 扩充到一个路径
%~nI - 仅将 %I 扩充到一个文件名
%~xI - 仅将 %I 扩充到一个文件扩展名
%~sI - 扩充的路径只含有短名
%~aI - 将 %I 扩充到文件的文件属性
%~tI - 将 %I 扩充到文件的日期/时间
%~zI - 将 %I 扩充到文件的大小
%~$PATH:I - 查找列在路径环境变量的目录(TTT提示:是环境变量path的目录),并将 %I 扩充到找到的第一个彻底合格的名称。若是环境变量名未被定义,或者没有找到文件,此组合键会扩充到空字符串
此外,还能够组合修饰符来获得多重结果:
%~dpI - 仅将 %I 扩充到一个驱动器号和路径
%~nxI - 仅将 %I 扩充到一个文件名和扩展名
%~fsI - 仅将 %I 扩充到一个带有短名的完整路径名
%~dp$PATH:i - 查找列在路径环境变量的目录,并将 %I 扩充到找到的第一个驱动器号和路径。
%~ftzaI - 将 %I 扩充到相似输出线路的 DIR
在以上例子中,%I 和 PATH 可用其余有效数值代替。%~ 语法用一个有效的 FOR 变量名终止。选取相似 %I 的大写变量名比较易读,并且避免与不分大小写的组合键混淆。
(以上是系统帮助的内容)
咱们能够看到每行都有一个大写字母"I",这个I其实就是咱们在FOR带入的变量,例如:
FOR /F "usebackq eol=; tokens=1,2* delims=,- " %%x in ("d:\test.txt") do echo %%x %%y %%z
这里咱们就要把那个x,y,z改为%~fx,%~fy,%~fz。
+++
TTT特例:如下是我根据以上说明做的一个综合的例子,能够直接复制到记事本里,保存为bat格式(c盘下任一目录),运行后,能够直观的看到扩展后的效果。
@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 --将变量扩充到相似输出线路的DIR
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 --将变量扩充到相似输出线路的DIR
Pause
TTT说明:
1,以上命令中,%%~fsI没法显示,估计是系统错误,由于%%~fI是扩充到一个彻底合格的路径名,%%~sI只含有短文件名,自己是相互矛盾的,因此出错。不知是系统的错误仍是在考咱们~~
2,以上命令若是保存在别的盘中,没法显示正确的驱动器和路径。
3,若是想要%%~dp$PATH:i正常显示,要保证环境变量path中确实有这个路径:C:\WINDOWS\system32。
下面依次说明一下:
+++
1、 ~I - 删除任何引号("),扩展 %I
---
这个变量的做用就如他的说明,删除引号!
删除引号规则以下(BAT兄补充!):
一、若字符串首尾同时存在引号,则删除首尾的引号;
二、若字符串尾不存在引号,则删除字符串首的引号;
三、若是字符串中间存在引号,或者只在尾部存在引号,则不删除。
龙卷风补充:无头不删,有头连尾删。
咱们来看这个例子,首先创建临时文件temp.txt,内容以下
"1111
"2222"
3333"
"4444"44
"55"55"55
也可创建个BAT文件代码以下:
@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
rem 上面创建临时文件,注意不成对的引号要加转义字符^,重定向符号前不要留空格
FOR /F "delims=" %%i IN (temp.txt) DO echo %%~i
pause
del temp.txt
执行后,咱们看CMD的回显以下:
1111 #字符串前的引号被删除了
2222 #字符串首尾的引号都被删除了
3333" #字符串前无引号,后面的引号保留
4444"44 #字符串前面的引号删除了,而中间的引号保留
55"55"55 #字符串前面的引号删除了,而中间的引号保留
请按任意键继续. . .
结果和以前temp.txt中的内容对比一下,咱们会发现第一、二、5行的引号都消失了,这就是删除引号~i的做用了!
+++
2、 %~fI - 将 %I 扩展到一个彻底合格的路径名
示例:
把代码保存放在随便哪一个地方,我这里就放桌面吧.
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~fi
pause
执行后显示内容以下
C:\Documents and Settings\Administrator\桌面\test.bat
C:\Documents and Settings\Administrator\桌面\test.vbs
当我把代码中的 %%~fi直接改为%%i
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%i
pause
执行后就会显示如下内容:
test.bat
test.vbs
经过对比,咱们很容易就看出没有路径了,这就是"将 %I 扩展到一个彻底合格的路径名"的做用,也就是若是%i变量的内容是一个文件名的话,他就会把这个文件所在的绝对路径打印出来,而不仅单单打印一个文件名,本身动手动实验下就知道了!
+++
3、 %~dI - 仅将 %I 扩展到一个驱动器号
看例子:
代码以下,我仍是放到桌面执行!
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~di
pause
执行后我CMD里显示以下
C:
C:
我桌面就两个文件test.bat,test.vbs,%%~di做用是,若是变量%%i的内容是一个文件或者目录名,他就会把他这文件或者目录所在的盘符号打印出来!
+++
4、 %~pI - 仅将 %I 扩展到一个路径
这个用法和上面同样,他只打印路径不打印文件名字
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~pi
pause
我就不打结果了,你们本身复制代码看结果吧,下面几个都是这么个用法,代码给出来,你们本身看结果吧!
+++
5、 %~nI - 仅将 %I 扩展到一个文件名
只打印文件名字
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~ni
pause
+++
6、 %~xI - 仅将 %I 扩展到一个文件扩展名
只打印文件的扩展名
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~xi
pause
+++
7、 %~sI - 扩展的路径只含有短名
打印绝对短文件名
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~si
pause
+++
8、 %~aI - 将 %I 扩展到文件的文件属性
打印文件的属性
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~ai
pause
+++
9、 %~tI - 将 %I 扩展到文件的日期/时间
打印文件创建的日期
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~ti
pause
+++
10、 %~zI - 将 %I 扩展到文件的大小
打印文件的大小
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~zi
pause
龙卷风补充:上面例子中的"delims=="能够改成"delims=",即不要分隔符
+++
11、 %~$PATH:I - 查找列在路径环境变量的目录,并将 %I 扩展到找到的第一个彻底合格的名称。若是环境变量名未被定义,或者没有找到文件,此组合键会扩展到空字符串
这是最后一个,和上面那些都不同,我单独说说!
而后在把这些代码保存为批处理,放在桌面。
@echo off
FOR /F "delims=" %%i IN (“notepad.exe”) DO echo %%~$PATH:i
pause
龙卷风补充:上面代码显示结果为C:\WINDOWS\system32\notepad.exe
他的意思就在PATH变量里指定的路径里搜索notepad.exe文件,若是有notepad.exe则会把他所在绝对路径打印出来,没有就打印一个错误!
(TTT说明,保存到桌面上,运行显示结果为:系统找不到文件 “notepad.exe”。查看环境变量path中确实有这个路径,不明缘由!后来发现了,原来是中文引号的缘由。
上面的命令应该写成:
FOR /F "delims=" %%i IN ("notepad.exe") DO echo %%~$PATH:i
)
最后发一个用批处理作一五子棋游戏:
@echo off&setlocal enabledelayedexpansion
mode con: lines=43 cols=110
set li39= A B C D E F G H I J K L M N O P Q R S
set li0= ┌─────────────────────────────────────┐
set li1=A│┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐│A
set var=1
for %%a in (!li39:~5^,-1!) do (set/a var+=2&set li!var!=%%a│├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤│%%a)
for /l %%a in (2,2,36) do (set li%%a= ││ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││)
set li37=S│└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘│S
set li38= └─────────────────────────────────────┘
set str=a b c d e f g h i j k l m n o p q r s
for %%a in (%str%) do (set/a .+=1,%%a=.&set z!.!=%%a)
set li5=!li5! 五 棋 子 人 机 对 战
set li7=!li7! 批 处 理
set li10=!li10! 电 脑 水 平 中 等
set li31=!li31! 由 netbenton 编写完成
set li33=!li33! 棋盘设计参照了 batman
title 批处理五子棋
set str=###################
set .=0
for /l %%a in (1,1,19) do (
set he%%a=!str!&set sh%%a=!str!
for /l %%b in (1,1,19) do set [%%a.%%b=0
)
set .=33
for /l %%a in (5,1,19) do (
set pi%%a=!str:~,%%a!&set ni%%a=!str:~,%%a!
set pi!.!=!str:~,%%a!&set ni!.!=!str:~,%%a!
set/a .-=1
)
set ●=○&set ○=●
set zhi=●
set say=say
::设置电脑IQ
set idea=@@@@#.1 #@@@@.5 @#@@@.4 @@@#@.2 @@#@@.3 vs0
#.1 #
.5
.3 $#
$#$.2 vs1#@@@##.2 ##@@@#.5 #@@#@#.3 #@#@@#.4 vs2 #@##@@#.4-5 #@@##@#.4-3 #@#@@.3-5 @#@@#.4-1 #@@@##.2-W-1##@@@#.5-W-6 vs3
set idea=!idea! ##@@@.4-W-5 @@@##.2-W-1 @##@@#.4-5 #@##@@.3-4 #@#@#@.4-2 @#@#@#.3-5 vs4 #
#.4-W-1-6 ##
#$#.5-W-1-6 #
$##.2-W-1-6 vs5 ##@@##.2-5-W-6-1 #@#@#.3-w-1-5 ##
$##.W-2-1
.W-3-4 $#
#$.W-2-5 ##
##.W-2-W-1-5 #$#$#.W-3-W-1-5 #$##$#.W-3-4
set idea=!idea! vs7 #$$$#.1-5 @@###.4-3 ###@@.3-4 ###@###.3-5-W-2-6-W-1-7 vs8 ###$###.3-5 vs9 @####.4 ####@.2 #$###.3 ###$#.3
set idea=!idea! ###@#.3 #@###.3 $####.3 ####$.3
.3 $#$##.2 ##$#$.4 #$##$.3 $##$#.3 $###$.3 vs10
set iqam=1000000000
:restart
(
setlocal enabledelayedexpansion
for /l %%a in (0,1,39) do (echo !li%%a!)
set li39=!li39! reboot从新开始,exit退出。
set li37=!li37! back 悔棋
set /p var=选择谁先下[ W,玩家 D,电脑 Q,退出 ]:
if /i "!var!" equ "Q" goto :quit
if /i "!var!" equ "D" (set onez=○&set towz=●&set hou=☆) else (set onez=●&set towz=○&set hou=★)
set a!onez!=电脑&set a!towz!=玩家
)
(
set ttr=!idea=%onez%!&set ttr=!ttr=%towz%!
set idea=
for %%a in (!ttr!) do (
for /f "tokens=1,2 delims=." %%b in ("%%a") do (set %%b=%%c&set idea=!idea! %%b)
)
set ttr=
set li27=!li27! !onez! !a%onez%!
set li25=!li25! !towz! !a%towz%!
set/a pos=10,poh=10&goto :getok
)
:loop
(if %zhi% equ %onez% goto :men
set .=
setlocal enabledelayedexpansion
for %%a in (!idea!) do (
set str=%%a
if "!str:~,2!" neq "vs" (
for %%b in (he sh) do (
set all=!%%b1!!%%b2!!%%b3!!%%b4!!%%b5!!%%b6!!%%b7!!%%b8!!%%b9!!%%b10!!%%b11!!%%b12!!%%b13!!%%b14!!%%b15!!%%b16!!%%b17!!%%b18!!%%b19!
if "!all:%%a=!" neq "!all!" (
for /l %%c in (1,1,19) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c.%%a.!iqam!
)
) )
for %%b in (pi ni) do (
set all=!%%b5!!%%b6!!%%b7!!%%b8!!%%b9!!%%b10!!%%b11!!%%b12!!%%b13!!%%b14!!%%b15!!%%b16!!%%b17!!%%b18!!%%b19!!%%b20!!%%b21!!%%b22!!%%b23!!%%b24!!%%b25!!%%b26!!%%b27!!%%b28!!%%b29!!%%b30!!%%b31!!%%b32!!%%b33!
if "!all:%%a=!" neq "!all!" (
for /l %%c in (5,1,33) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c.%%a.!iqam!
)
) )
) else (
set/a "iqam=(iqam+1)/8"
if %%a equ vs8 if defined . goto :get
if %%a equ vs9 if defined . goto :get
)
))
if defined . (goto :get)
echo. 已经和棋了
pause
endlocal&goto :restart
:men
(
set/a .=lips-1&for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%hou%!%%b:~%%c!)
set li38=!li38![%悔:~,24%]
cls
for /l %%a in (0,1,39) do (echo !li%%a!)
for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%zhi%!%%b:~%%c!)
set li38=%li38%
set /p user=!say:say=%error%! [列前,行后]:
if "!user!" equ "reboot" endlocal&goto :restart
if "!user!" equ "exit" goto :quit
if "!user!" equ "back" call :悔&goto :men
set/a pos=!user:~0,1!,poh=!user:~1,2!,var=pos-1 2>nul
if not defined [!poh!.!pos! set error=输入点不存在 &goto :men
)
if "!he%poh%:~%var%,1!" neq "#" set error=该点已经有子 &goto men
goto :getok
:get
set `=
::取最佳的走法
for /l %%z in (!.!,-1,1) do (
for /f "tokens=1,2,3 delims=." %%1 in ("!put%%z!") do (
for /f "tokens=1-4" %%a in ("%%1 %%2") do (
set iqm=%%3
set vara=!%%a%%b:*%%c=!srqponmlkjihgfedcba0
for %%4 in (!%%2:-^=;!) do (
if "%%4" equ "W" (set/a iqm=iqm/5*3) else (
set/a var=!vara:~19,1!+%%4
if "%%a" equ "he" (set/a poh=%%b,pos=20-var)
if "%%a" equ "sh" (set/a poh=20-var,pos=%%b)
if %%b lss 19 (set/a var=%%b-var+1) else (set/a var=38-%%b-var+1)
if "%%a" equ "pi" (if %%b lss 19 (set/a pos=var,poh=%%b-var+1) else (set/a poh=20-var,pos=%%b-19+var))
if "%%a" equ "ni" (if %%b lss 19 (set/a pos=var,poh=19-%%b+var) else (set/a poh=var,pos=%%b-19+var))
if not defined R!pos!R!poh!R set /a `+=1&set ram!`!=R!pos!R!poh!R
set/a R!pos!R!poh!R+=iqm
)
)
)
)
)
set rmk=0
for /l %%a in (1,1,!`!) do (
for %%b in (!ram%%a!) do (
for %%c in (!%%b!) do (
if %%c gtr !rmk! set/a rmk=%%c,.=0
if %%c equ !rmk! set rmz!.!=%%b&set/a .+=1
)
) )
set/a .=!random!%%.
for /f "tokens=1,2 delims=R" %%a in ("!rmz%.%!") do (set/a pos=%%a,poh=%%b)
rem start set r^&echo !.!^&pause^&exit
endlocal&set/a pos=%pos%,poh=%poh%set say=say !z%pos%!!z%poh%!(%poh%)&set error=电脑最后下在::getokset zhi=!%zhi%!&set win=!zhi!!zhi!!zhi!!zhi!!zhi!(set/a piph=poh+pos-1,lips=pos*2+1,niph=19+pos-poh,liph=poh*2-1if !piph! lss 19 (set/a pips=pos) else (set/a pips=20-poh)if !niph! lss 19 (set/a nips=pos) else (set/a nips=poh)for %%a in ("li!liph! !lips!" "he!poh! !pos!" "sh!pos! !poh!" "pi!piph! !pips!" "ni!niph! !nips!") do ( for /f "tokens=1,2" %%b in (%%a) do ( set/a .=%%c-1 for %%d in (!.!) do (set %%b=!%%b:~0,%%d!%zhi%!%%b:~%%c!) if "!%%b:%win%=!" neq "!%%b!" set win=y )))(set/a asc%zhi%+=1set 悔= !z%pos%!!z%poh%!!悔!if !win! neq y goto :loop)for /l %%a in (0,1,39) do (echo !li%%a!)set/p= !a%zhi%! %zhi%子 第!asc%zhi%!手 !z%pos%!!z%poh%!(%poh%) 胜出 <nulpauseendlocal&goto :restart:悔if not defined 悔 goto :eofif "!悔:~6,1!" equ "" goto :eoffor %%a in (!悔:~^,6!) do (set str=%%aset/a poh=!str:~-1!,pos=!str:~,1!set/a piph=poh+pos-1,niph=19+pos-poh,liph=poh*2-1,lips=pos*2+1if !piph! lss 19 (set/a pips=pos) else (set/a pips=20-poh)if !niph! lss 19 (set/a nips=pos) else (set/a nips=poh)for %%a in ( "he!poh! !pos!" "sh!pos! !poh!" "pi!piph! !pips!" "ni!niph! !nips!") do ( for /f "tokens=1,2" %%b in (%%a) do ( set/a .=%%c-1 for %%d in (!.!) do (set %%b=!%%b:~0,%%d!#!%%b:~%%c!) ))for /f "tokens=1,2" %%b in ("li!liph! !lips!") do ( set/a .=%%c-1 for %%d in (!.!) do (set %%b=!%%b:~0,%%d!┼!%%b:~%%c!)))set/a asc%zhi%-=1set 悔=!悔:~6!set error=你悔棋,耍赖皮!if not defined 悔 goto :eofset/a poh=!悔:~2,1!,pos=!悔:~1,1!,liph=poh*2-1,lips=pos*2+1set say=say !z%pos%!!z%poh%!(%poh%)goto :eof:quittaskkill /fi "WINDOWTITLE eq 批处理五子棋*" /im cmd.exe