批处理命令 For循环命令具体解释!

批处理for命令具体解释
FOR这条命令基本上都被用来处理文本,但还有其它一些好用的功能!
看看他的基本格式(这里我引用的是批处理中的格式,直接在命令行仅仅须要一个%号)
FOR 參数 %%变量名 IN (相关文件或命令) DO 运行的命令
參数:FOR有4个參数 /d /l /r /f 他们的作用我在以下用样例解释
%%变量名 :这个变量名能够是小写a-z或者大写A-Z,他们区分大写和小写,FOR会把每一个读取到的值给他;
IN:命令的格式,照写就是了;
(相关文件或命令) :FOR要把什么东西读取然后赋值给变量,看以下的样例
do:命令的格式,照写就是了!
运行的命令:对每一个变量的值要运行什么操作就写在这.
能够在CMD输入for /?看系统提供的帮助!对照一下
FOR %%variable IN (set) DO command [command-parameters]
   %%variable   指定一个单一字母可替换的參数。
   (set)    指定一个或一组文件。能够使用通配符。
   command 指定对每一个文件运行的命令。
   command-parameters
         为特定命令指定參数或命令行开关。

如今開始讲每一个參数的意思
/d
仅为文件夹
假设 Set (也就是我上面写的 "相关文件或命令") 包括通配符(* 和 ?),将对与 Set 相匹配的每一个目
录(而不是指定文件夹中的文件组)运行指定的 Command。
系统帮助的格式:FOR /D %%variable IN (set) DO command
他主要用于文件夹搜索,不会搜索文件,看这种样例
@echo off
for /d %%i in (*) do @echo %%i
pause
把他保存放在C盘根文件夹运行,就会把C盘文件夹下的所有文件夹名字打印出来,而文件名称字一个也不显示!
在来一个,比方我们要把当前路径下文件夹的名字仅仅有1-3个字母的打出来
@echo off
for /d %%i in (???) do @echo %%i
pause
这种话假设你当前文件夹下有文件夹名字仅仅有1-3个字母的,就会显示出来,没有就不显示了

思考题目:
@echo off
for /d %%i in (window?) do @echo %%i
pause
保存到C盘下运行,会显示什么呢?自己看吧!
/D參数仅仅能显示当前文件夹下的文件夹名字,这个大家要注意!

/R
递归
进入根文件夹树 [Drive:]Path,在树的每一个文件夹中运行 for 语句。假设在 /R 后没有指定文件夹,则觉得是
当前文件夹。假设 Set 仅仅是一个句点 (.),则仅仅枚举文件夹树。
系统帮助的格式:FOR /R [[drive:]path] %%variable IN (set) DO command
上面我们知道,/D仅仅能显示当前路径下的文件夹名字,那么如今这个/R也是和文件夹有关,他能干嘛呢?放心他比
/D强大多了!
他能够把当前或者你指定路径下的文件名称字所有读取,注意是文件名称字,有什么用看样例!
@echo off
for /r c:/ %%i in (*.exe) do @echo %%i
pause
咋们把这个BAT保存到D盘随便哪里然后运行,我会就会看到,他把C盘根文件夹,和每一个文件夹的子文件夹以下所有
的EXE文件都列出来了,这里的c:/就是文件夹了。
再来一个
@echo off
for /r %%i in (*.exe) do @echo %%i
pause
參数不一样了,这个命令前面没加那个C:/也就是搜索路径,这样他就会以当前文件夹为搜索路径,比方你这
个BAT你把他防灾d:/test文件夹下运行,那么他就会把D:/test文件夹和他以下的子文件夹的所有EXE文件列出
来!!!

/L
迭代数值范围
使用迭代变量设置起始值 (Start#),然后逐步运行一组范围的值,直到该值超过所设置的终止值 (End#)
。/L 将通过对 Start# 与 End# 进行比較来运行迭代变量。假设 Start# 小于 End#,就会运行该命令。
假设迭代变量超过 End#,则命令解释程序退出此循环。还能够使用负的 Step# 以递减数值的方式逐步执
行此范围内的值。比如,(1,1,5) 生成序列 1 2 3 4 5,而 (5,-1,1) 则生成序列 (5 4 3 2 1)。语法是:
系统帮助的格式:for /L %% Variable in (Start#,Step#,End#) do Command
比如:
@echo off
for /l %%i in (1,1,5) do @echo %%i
pause
保存运行看效果,他会打印从1 2 3 4 5   这样5个数字
(1,1,5)这个參数也就是表示从1開始每次加1直到5终止!
再看这个样例
@echo off
for /l %%i in (1,1,5) do start cmd
pause
运行后是不是吓了一跳,怎么多了5个CMD窗体,呵呵!假设把那个 (1,1,5)改成 (1,1,65535)会有什么结果,
我先告诉大家,会打开65535个CMD窗体....这么多你不死机算你强!
当然我们也能够把那个start cmd改成md %%i 这样就会建立指定个文件夹了!!!名字为1-65535
看完这个被我赋予破坏性质的參数后,我们来看最后一个參数
/f

含有/F的for具体说明
含有/F的for有非常大的用处,在批处理中使用的最多,使用方法例如以下:
格式:
FOR /F ["options"] %%i IN (file) DO command
FOR /F ["options"] %%i IN ("string") DO command
FOR /F ["options"] %%i IN ('command') DO command

这个可能是最经常使用的,也是最强的命令,主要用来处理文件和一些命令的输出结果。
file代表一个或多个文件
string 代表字符串
command代表命令
["options"] 可选
对于FOR /F %%i IN (file) DO command
file为文件名称,依照官方的说法是,for会依次将file中的文件打开,而且在进行到下一个文件之前将每一个文件读取到内存,依照每一行分成一个一个的元素,忽略空白的行,看个样例。
假如文件a.txt中有例如以下内容:

第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列

你想显示a.txt中的内容,会用什么命令呢?当然是type,type a.txt
for也能够完毕相同的命令:
for /f %%i in (a.txt) do echo %%i
还是先从括号运行,由于含有參数/f,所以for会先打开a.txt,然后读出a.txt里面的所有内容,把它作为一个集合,而且以每一行作为一个元素,所以会产生这种集合,

{“第1行第1列 第1行第2列 第1行第3列”, //第一个元素
“第2行第1列 第2行第2列 第2行第3列”, //第二个元素
“第3行第1列 第3行第2列 第3行第3列”} //第三个元素

集合中仅仅有3个元素,相同用%%i依次取代每一个元素,然后运行do后面的命令。
具体过程:

用%%i取代“第1行第1列 第1行第2列 第1行第3列”,运行do后面的echo %%i,显示“第1行第1列 第1行第2列 第1行第3列”,
用%%i取代“第2行第1列 第2行第2列 第2行第3列”,运行echo %%i,显示“第2行第1列 第2行第2列 第2行第3列”,
依次,直到每一个元素都取代完为止。

为了加强理解/f的作用,请运行一下两个命令,对照就可以明确:

for /f %%i in (a.txt) do echo %%i //这个会显示a.txt里面的内容,由于/f的作用,会读出a.txt中
的内容。
for %%i in (a.txt) do echo %%i //而这个仅仅会显示a.txt这个名字,并不会读取当中的内容。

通过上面的学习,我们发现for /f会默认以每一行来作为一个元素,可是假设我们还想把每一行再分解更小的内容,该怎么办呢?不用操心,for命令还为我们提供了更具体的參数,使我们将每一行分为更小的元素成为可能。
它们就是:delims和tokens
delims 用来告诉for每一行应该拿什么作为分隔符,默认的分隔符是空格和tab键
比方,还是上面的文件,我们运行以下的命令:

for /f "delims= " %%i in (a.txt) do echo %%i

显示的结果是:

第1行第1列
第2行第1列
第3行第1列

为什么是这种呢。由于这里有了delims这个參数,=后面有一个空格,意思是再将每一个元素以空格切割,默认是仅仅取切割之后的第一个元素。
运行过程是:

将第一个元素“第1行第1列 第1行第2列 第1行第3列”分成三个元素:“第1行第1列” “第1行第2列” “第1行第3列”,它默认仅仅取第一个,即“第1行第1列”,然后运行do后面的命令,依次类推。

可是这样还是有局限的,假设我们想要每一行的第二列元素,那又怎样呢?
这时候,tokens跳出来说,我能做到。
它的作用就是当你通过delims将每一行分为更小的元素时,由它来控制要取哪一个或哪几个。
还是上面的样例,运行例如以下命令:

for /f "tokens=2 delims= " %%i in (a.txt) do echo %%i

运行结果:

第1行第2列
第2行第2列
第3行第2列
假设要显示第三列,那就换成tokens=3。
同一时候tokens支持通配符*,以及限定范围。
假设要显示第二列和第三列,则换成tokens=2,3或tokens=2-3,假设还有很多其它的则为:tokens=2-10之类的。
此时的命令为:

for /f "tokens=2,3 delims= " %%i in (a.txt) do echo %%i %%j

怎么多出一个%%j?
这是由于你的tokens后面要取每一行的两列,用%%i来替换第二列,用%%j来替换第三列。
而且必须是依照英文字母顺序排列的,%%j不能换成%%k,由于i后面是j
运行结果为:

第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列
对以通配符*,就是把这一行所有或者这一行的剩余部分当作一个元素了。
比方:

for /f "tokens=* delims= " %%i in (a.txt) do echo %%i

运行结果为:

第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
事实上就跟for /f %%i in (a.txt) do echo %%i的运行结果是一样的。
再如:

for /f "tokens=2,* delims= " %%i in (a.txt) do echo %%i %%j
运行结果为:

第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列

用%%i取代第二列,用%%j取代剩余的所有
最后还有skip合eol,这俩个简单,skip就是要忽略文件的前多少行,而eol用来指定当一行以什么符号開始时,就忽略它。
比方:

for /f "skip=2 tokens=*" %%i in (a.txt) do echo %%i
结果为:

第3行第1列 第3行第2列 第3行第3列
用skip来告诉for跳过前两行。
假设不加tokens=*的话,运行结果为:

第3行第1列
不知道怎么回事。
再如,当a.txt内容变成:

.第1行第1列 第1行第2列 第1行第3列
.第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
运行for /f "eol=. tokens=*" %%i in (a.txt) do echo %%i结果是:

第3行第1列 第3行第2列 第3行第3列
用eol来告诉for忽略以“.”开头的行。
相同也必须加tokens=*,否则仅仅会显示“第3行第1列

======================================================

终极dos批处理循环命令具体解释
格式:FOR [參数] %%变量名 IN (相关文件或命令)   DO 运行的命令
  作用:对一个或一组文件,字符串或命令结果中的每个对象运行特定命令,达到我们想要的结果。
  注意:在批处理文件里使用 FOR 命令时,指定变量请使用 %%variable,而不要用 %variable。变量名称是区分大写和小写的,所以 %i 不同于 %I.
  关于:for命令能够带參数或不带參数,带參数时支持以下參数:/d /l /r /f
  以下分别解释一下

  ===
  零:无參数时:
  ---
  FOR %variable IN (set) DO command [command-parameters]
  %variable 指定一个单一字母可替换的參数。
  (set)      指定一个或一组文件。能够使用通配符。
  command    指定对每一个文件运行的命令。
  command-parameters
  为特定命令指定參数或命令行开关。

  TTT演示样例:
  for %%i in (t*.*) do echo %%i --显示当前文件夹下与t*.*相匹配的文件(仅仅显示文件名称,不显示路径)
  for %%i in (d:/mydocuments/*.doc) do @echo %%i --显示d:/mydocuments/文件夹下与*.doc相匹配的文件
  ===
  一、參数 /d (參数仅仅能显示当前文件夹下的文件夹名字)
  ---
  格式:FOR /D %variable IN (set) DO command [command-parameters]
  这个參数主要用于文件夹搜索,不会搜索文件,/D 參数仅仅能显示当前文件夹下的文件夹名字。(TTT特别说明:仅仅会搜索指定文件夹下的文件夹,不会搜索再下一级的文件夹。)

  TTT演示样例:
  for /d %%i in (c:/*) do echo %%i --显示c盘根文件夹下的全部文件夹
  for /d %%i in (???) do echo %%i --显示当前文件夹下名字仅仅有1-3个字母的文件夹

  ===
  二、參数 /R (搜索指定路径及全部子文件夹中与set相符合的全部文件)
  ---
  格式:FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
  此命令会搜索指定路径及全部子文件夹中与set相符合的全部文件,注意是指定路径及全部子文件夹。

  1、set中的文件名称假设含有通配符(?或*),则列举/R參数指定的文件夹及其以下的所用子文件夹中与set相符合的全部文件,无相符文件的文件夹则不列举。
  2、假设set中为详细文件名称,不含通配符,则枚举该文件夹树(即列举该文件夹及其以下的全部子文件夹)(并在后面加上详细的文件名称),而无论set中的指定文件是否存在。
  例:for /r c:/ %%i in (*.exe) do echo %%i --把C盘根文件夹,和每一个文件夹的子文件夹以下全部的EXE文件都列出来了!!!!

  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存在的文件夹

  ===
  三、參数 /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个目录

四、參数 /F (使用文件解析来处理命令输出、字符串及文件内容。)
  ---
  这个參数是最难的,參数又多,先简单的解释一下:for命令带这个參数能够分析文件内容,字符串内容或某一命令输出的结果,并通过设置option得我们想要的结果。
  下面是某高手的解释,感觉有点太专业了,自觉得不太easy理解,也列一下:
  [迭代及文件解析--使用文件解析来处理命令输出、字符串及文件内容。使用迭代变量定义要检查的内容或字符串,并使用各种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]

  或者,假设有 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) OPTIONkeyword具体解释:
  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"參数替代默认解析操作。这个带引號的字符串包含一个或多个指定不同解析选项的keyword。

  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]
  结果大家能够试一下,非常easy就明确的。
  ===
  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。
 以下依次说明一下:
  +++
  一、 ~I       - 删除不论什么引號("),扩展 %I
  ---
  这个变量的作用就如他的说明,删除引號!
  删除引號规则例如以下(BAT兄补充!):
  1、若字符串首尾同一时候存在引號,则删除首尾的引號;
  2、若字符串尾不存在引號,则删除字符串首的引號;
  3、假设字符串中间存在引號,或者仅仅在尾部存在引號,则不删除。
  龙卷风补充:无头不删,有头连尾删。

  我们来看这个样例,首先建立暂时文件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中的内容对照一下,我们会发现第1、2、5行的引號都消失了,这就是删除引號~i的作用了!
  +++
  二、 %~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
  通过对照,我们非常easy就看出没有路径了,这就是"将 %I 扩展到一个全然合格的路径名"的作用,也就是假设%i变量的内容是一个文件名称的话,他就会把这个文件所在的绝对路径打印出来,而不仅仅单单打印一个文件名称,自己动手动实验下就知道了!
  +++
  三、 %~dI        - 仅将 %I 扩展到一个驱动器号
  看样例:
  代码例如以下,我还是放到桌面运行!
  FOR /F "delims==" %%i IN ('dir /b') DO @echo   %%~di
  pause
  运行后我CMD里显演示样例如以下
  C:
  C:
  我桌面就两个文件test.bat,test.vbs,%%~di作用是,假设变量%%i的内容是一个文件或者文件夹名,他就会把他这文件或者文件夹所在的盘符号打印出来!

  +++
  四、 %~pI        - 仅将 %I 扩展到一个路径
  这个使用方法和上面一样,他仅仅打印路径不打印文件名称字
  FOR /F "delims==" %%i IN ('dir /b') DO @echo   %%~pi
  pause
  我就不打结果了,大家自己复制代码看结果吧,以下几个都是这么个使用方法,代码给出来,大家自己看结果吧!

  +++
  五、 %~nI        - 仅将 %I 扩展到一个文件名称
  仅仅打印文件名称字
  FOR /F "delims==" %%i IN ('dir /b') DO @echo   %%~ni
  pause

  +++
  六、 %~xI        - 仅将 %I 扩展到一个文件扩展名
  仅仅打印文件的扩展名
  FOR /F "delims==" %%i IN ('dir /b') DO @echo   %%~xi
  pause

  +++
  七、 %~sI        - 扩展的路径仅仅含有短名
  打印绝对短文件名称
  FOR /F "delims==" %%i IN ('dir /b') DO @echo   %%~si
  pause

  +++
  八、 %~aI        - 将 %I 扩展到文件的文件属性
  打印文件的属性
  FOR /F "delims==" %%i IN ('dir /b') DO @echo   %%~ai
  pause

  +++
  九、 %~tI        - 将 %I 扩展到文件的日期/时间
  打印文件建立的日期
  FOR /F "delims==" %%i IN ('dir /b') DO @echo   %%~ti
  pause

  +++
  十、 %~zI        - 将 %I 扩展到文件的大小
  打印文件的大小
  FOR /F "delims==" %%i IN ('dir /b') DO @echo   %%~zi
  pause
  龙卷风补充:上面样例中的"delims=="能够改为"delims=",即不要分隔符

  +++
  十一、 %~$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 $#$$$.4 $$$#$.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 #$$#$#.3-W-6-1 #$#$$#.4-W-1-6 ##$$$#.5-W-1-6 #$$$##.2-W-1-6 vs5 ##@@##.2-5-W-6-1 #@#@#.3-w-1-5 ##$$$.W-4-5 $$$##.W-2-1 $$##$.W-2-3 $##$$.W-3-4 $#$$#.W-4-1 $#$#$.W-4-2 #$$#$.W-2-5 ##$$#.W-4-W-1-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 ###$$.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=电脑最后下在:
:getok
set 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-1
if !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%+=1
set 悔= !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%) 胜出    <nul
pause
endlocal&goto :restart
:悔
if not defined 悔 goto :eof
if "!悔:~6,1!" equ "" goto :eof
for %%a in (!悔:~^,6!) do (set str=%%a
set/a poh=!str:~-1!,pos=!str:~,1!
set/a piph=poh+pos-1,niph=19+pos-poh,liph=poh*2-1,lips=pos*2+1
if !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%-=1
set 悔=!悔:~6!
set error=你悔棋,耍赖皮!
if not defined 悔 goto :eof
set/a poh=!悔:~2,1!,pos=!悔:~1,1!,liph=poh*2-1,lips=pos*2+1
set say=say !z%pos%!!z%poh%!(%poh%)
goto :eof
:quit
taskkill /fi "WINDOWTITLE eq 批处理五子棋*" /im cmd.exe

上一篇:Win10开机提示Resume from Hibernation该怎么办?


下一篇:C#中使用Redis学习一 windows安装redis服务器端和客户端