for %a in ("%path:;=" "%") do @echo %~a
若path=c:/dos;c:/windows;c:/tools
echo %path:;=" "%
结果为:c:/dos" "c:/windows" "c:/tools
echo "%path:;=" "%"
结果为:"c:/dos" "c:/windows" "c:/tools"
----------
原帖位置 http://www.cn-dos.net/forum/viewthread.php?tid=38347
以下语句如果用%?形式全部在CMD命令提示符下运行,用%%?形式是在批处理条件下运行!
1.FOR 语句
for %a in (****) do @echo %a 这种形式的FOR语句是最为简单的一种,没有/D /R /F等参数开关,用法也很普通,下面给大家简单介绍一下
。
C:/>for %a in (aa.txt bb.txt cc.txt) do @echo %a
运行结果如下:
aa.txt
bb.txt
cc.txt
当然了,我们使用通配符也是可以的
for %a in (*) do @echo %a
for %a in (a?*.txt) do @echo %a
等等一些方法都是大同小异。
用FOR语句可以简化运行命令的重复性,在一定程度上提高了运行速度,减少了代码量。
for %a in (*.cmd *.txt) do @echo %a
显示当前目录下所有后缀名为.CMD 和.TXT的文件,这对处理多个文件提供了方便。
当然我们也可以这样用它,以%PATH%环境变量为例,如下:
for %a in ("%path:;=" "%") do @echo %~a
运行结果如下:
C:/WINDOWS/system32
C:/WINDOWS
C:/WINDOWS/System32/Wbem
目的就是把PATH环境变量的每个路径分离出来进行逐行显示
2.FOR /D 语句
打开CMD命令提示符,在传说中的黑色框中输入如下语句:
C:/>for /d %a IN (*) do @echo %a
9527
ccp
Documents and Settings
ppw
Program Files
RavBin
WINDOWS
WINNT
结果如上,显示当前目录下各个目录名称,不包括文件名,对于 (*)--括号中的内容我们称之为"集", 其实我们也可以用(*.*)形式运行,意
思是指全部内容,其实它就是我们熟悉的通配符,而我理解的/D的作用跟过滤效果差不多(/D-DIRECTORY的缩写)就是只显示目录名!
同样的,我们运行如下语句:
C:/>for /d %a in (w*) do @echo %a
结果如下:
WINDOWS
WINNT
这条语句就是显示以W开头的目录名称!(不区分大小写)
C:/>for /d %a in (w*s) do @echo %a
WINDOWS
不用我说了吧,这跟通配符的用法有关。
我们在说说用?作为通配符使用在/D参数上
C:/>for /d %a in (w?nnt) do @echo %a---成功执行,不用说有WINNT目录,如果执行不成功表示没有此目录
WINNT
C:/>for /d %a in (w??nnt) do @echo %a--不成功,由于通配符的特性,只能匹配像WIINNT这样的目录
C:/>for /d %a in (w?nnt?) do @echo %a--成功,也有两个??为何成功,因为最后结尾处是?通配符,可以匹配如winnt winntt样式的目录
WINNT
好了,不说通配符的事情了,继续...
3.FOR /R 语句
本人理解/R这个R是recursive的缩写,也就是递归的意思。
递归嘛,就是对其目录及其子目录的所有文件进行操作,这全部归功于/R这个参数,下面我们举例说明一下用法:
for /r %a in (*) do @echo %a 同 for /r . %a in (*) do @echo %a 效果是一样的,不指定或者用.表示当前目录
此句的作用是显示当前目录及其子目录下的所有文件,当然也可以指定我们要操作的目录。
for /r d:/ansi %a in (*.txt) do @echo %a
显示D:/ANSI目录及其子目录下所有的.TXT的文件名称
如果我们指定的目录名含有空格可以使用双引号来解决。
for /r "c:/program files" %a in (ok.*) do @echo %a
这样我们就可以显示c:/program files目录及其子目录下文件名为OK的所有文件。
虽然FOR /R 语句官方帮助提到如果集的内容为一个.点,可以列举该目录树,但我总觉得不爽,有的时候为了美观没有必要偷懒,其实列举目
录树我们可以用/D /R两个参数的联合使用来实现,如下:
for /d /r "c:/program files" %a in (*) do @echo %a---美观
for /r "c:/program files" %a in (.) do @echo %a ----感觉不爽
这样就可以列举c:/program files目录下所有目录及其子目录(不包括文件),把集设置为点号也未尝不可。
4.FOR /L 语句
FOR /L %%parameter IN (start,step,end) DO command 我们可以这样看待这个语句,这样便于大家理解。
for /l %a in (1,1,10) do @echo %a ------正序显示
for /l %a in (10,-1,0) do @echo %a------倒序显示
循环显示1-10这10个数字,我们可以随意修改这些数字,但是我们应该注意一些问题,如下:
(start,step,end)
step为正数时,end>=start
step为负数时,end<=start
当step为零时,情况如下:
start>end 运行无效
start<=end 无限循环
我们还需要知道这三个数字之间可以用其他分隔符,例如:
for /l %a in (1,1,10) do @echo %a
for /l %a in (1 1 10) do @echo %a
for /l %a in (1=1=10) do @echo %a
for /l %a in (1,1,10) do @echo %a
for /l %a in (1<tab>1<tab>10) do @echo %a
这五条语句运行的效果是一样的,<tab>---TAB键
5.FOR /F 语句
可算到了/F参数啦,很多新手对其掌握的不是太好,关键是要灵活应用就好,用多了就习惯了,习惯了就好了.....
首先我们要进行介绍的就是/F参数下的这几个选项:
delims=xxx 以xxx作为FOR语句的分隔符,可以是多个符号或字符,默认值是一个空格
skip=n 在文件开始跳过的行数。默认值是零,如果SKIP=X(X如果是0或者负数语句执行都会失败,因为零或负数根本就没有意义)
eol=; 指一个行注释字符的结尾,默认指是分号(;)
tokens=n 指每行准备要被替代的符合条件的标记,默认值是1
usebackq 使用后引号进行FOR语句的处理。usebackq=use back quote(` `--属于后引号)
我知道,对于一些FOR语句的帮助中在说明这几个选项的时候很多人对其描述的内容不是很清楚,以上说明其实也不是那么好理解,我只是
粗略介绍一下,想要真正理解这些选项的用途还要在实际应用中去体会,这样会更好的认识这些选项的含义。
我会列举大量实例以便说明各个选项的用途:
首先要让大家清楚/F在处理的时候有三种形式:
FOR /F "选项" %? IN (文件名) DO command
FOR /F "选项" %? IN ("字符串") DO command
FOR /F "选项" %? IN ('命令') DO command
1.我们首先要说DELIMS这个选项的一些应用
① for /f "delims==" %? in ('set') do @echo %?
以等号作为分隔符处理SET命令运行的结果,显示所有的变量名称。
② 例如我们有ansi.txt文件,内容如下:
AAA BBB CCC
DDD EEE BBB
UUU LLL PPP
for /f "delims=" %a in (ansi.txt) do @echo %a 我们没有给delims选项赋值,所以没有任何分隔符,就是显示文件的全部内容,包括
行首行尾有空格的情况。
2.TOKENS选项的一些应用
①我们还拿ansi.txt文件做测试
for /f "tokens=2" %a in (ansi.txt) do @echo %a
| AAA | BBB | CCC |
tokens=1 tokens=2 tokens=3
默认以空格为分隔符,TOKENS=2取得第二个标记,所以以上这条语句取得了BBB EEE LLL 3个数值。
②for /f "tokens=*" %a in (ansi.txt) do @echo %a
tokens=*取得所有标记,这种情况显示出来的结果会去掉行首前的空格,不会去掉行尾空格。
例如:
[ AAA BBB CCC ]
[ DDD DSDFDFDF DDFDF ]
[VVSDF S ]
[]这个只是为了显示出空格的位置,执行以上语句结果如下:
[AAA BBB CCC ]
[DDD DSDFDFDF DDFDF ]
[VVSDF S ]
③for /f "tokens=1,3-5*" %a in ("A B C D E F G H") do @echo %a %b %c %d %e
A B C D E F G H
tokens 1 2 3 4 5 6 7 8
%a %b %c %d 最后一个标记为*,所以从标记6往后的所有标记都赋值给 %e
最后得到结果为: A C D E F G H
3.EOL选项
很多人在用FOR语句的时候都不是太过注重这个EOL选项,其实它很烦人的
我们都知道FOR语句中eol选项默认忽略是以分号(;)开头的行
for /f "eol= delims=" %a in (" Hello World!") do @echo %a-----无任何显示,忽略了以空格开头的行
for /f "delims= eol=" %a in (""Hello World!^") do @echo %a----无任何显示,忽略了以双引号开头的行
两条语句虽然只是eol 和 delims选项掉换了位置但是意义却不同
第一条eol在前,eol= 表示忽略以空格开头的行!!!
第二条eol在选项里的最后一个,其实他会忽略以"双引号开头的行,是不是挺烦人的!
由此看来,EOL选项不论是在哪个位置,他都是以等号后面的那个字符做为判断标准的
那我们怎么来解决这个棘手的问题呢?
我们可以用一些不常用的特殊字符或符号做为EOL的值,虽然不是很完美,但是一般情况应该可以应付啦!
例如:for /f "eol=退格键 delims=" %%a in ("xxxxxxxxxxxx") do @echo.%%a
其实对于解决一个问题来说最关键的是我们怎么去看待这个问题!
4.SKIP=n 选项
这个选项其实没有什么好说的,大家也都知道,也没有什么特殊的用法,只不过注意几个问题就可以啦
首先n的值不能是0或者负数,否则会报错!这也是合情合理的。
for /f "skip=5" %a in (xxx.txt) @echo.%a
跳过xxx.txt文件前5行,然后进行操作,当然我们也可以使用以下语句来实现:
for /f "skip=00000000005" %a in (xxx.txt) @echo.%a 呵呵,只要0后面有数字效果一样,当然,如果你指定SKIP值大于文件本身的行
数,那不会有任何显示啦!!!
5.USEBACKQ 使用后引号选项
其实最初在学习FOR语句时我实在是不理解他帮助中所说的后引号到底有什么好处?也不理解他帮助中所讲的意思,我理解能力有问题。
①在集以后引号形式执行时必须用此选项
for /f "usebackq delims==" %a in (`set`) do @echo %a
②当文件名中含有空格的时候可以使用USEBACKQ选项处理,这样很方便。
for /f "usebackq tokens=*" %a in ("c:/hello world.txt") do @echo.%a
在默认情况下FOR语句处理文件的时候是不能够加上双引号的,在以字符串的形式处理的时候才会使用双引号!
如果我们使用如下语句就会出错:
for /f "tokens=*" %a in (c:/hello world.txt) do @echo.%a
因为他处理的对象是hello这个文件,而不是hello world.txt文件。这点我希望大家能够分辨清楚。
③那我们想用usebackq选项还要处理字符串该怎么办呢? 难道也使用双引号吗? 不,我们使用单引号
for /f "usebackq delims=" %a in ('Hello Word!') do @echo.%a
我看到国外有些网站说,如果字符串中含有双引号,可以使用usebackq来进行处理,也就是如下实例:
for /f "usebackq delims=" %a in ('Hello "AnsiPeter" Word!') do @echo.%a
其实正常语句也可以正常显示,用USEBACKQ选项可能便于区分吧,我是这样想的,如下:
for /f "delims=" %a in ("Hello "AnsiPeter" Word!") do @echo.%a
好了,基本上这几个选项说完了,下面我们来说说一些需要注意的问题:
for /f "tokens=1,2,3 delims=. " %a in ("a.b.c d.e f") do @echo %a %b %c
这是一条很普通的FOR语句
执行结果是:a b c delims选项是以空格和.作为分隔符的,如果改变成以下会是什么情况呢?
for /f "tokens=1,2,3 delims= ." %a in ("a.b.c d.e f") do @echo %a %b %c
报错,此时不应有 ."。这是为什么呢?
我是这样理解的,FOR/F语句中的每个选项之间是以空格分开的,但除了eol选项,因为eol选项是以等号后面的字符做为判断标准的,不管
EOL在选项的那个位置都是一样的,上面我们已经介绍过了
在如下:
for /f "delims= . tokens=1,2,3" %a in ("a.b.c d.e f") do @echo %a %b %c
报错,不用再说了吧,他默认把.作为FOR语句/F其中的一个选项,但根本就不包括这个选项当然要报错了,在如下:
for /f "delims=. tokens=1,2,3" %%a in ("a.b.c d.e f") do @echo %a %b %c
在这句.后面是两个空格,执行结果呢?如下:
结果:a b c d
这说明根本没有把空格当作分隔符号,如果当成分隔符号结果应该是:a b c才对
又如下:
for /f "delims= tokens=1,2,3" %%a in (" hello world ansi") do @echo %%a
显示结果:hello world ansi
for /f "tokens=1,2,3 delims= " %%a in (" hello world ansi") do @echo %%a
显示结果:hello
delims后面同样是空格,为什么有区别呢?
第一条语句是没有赋给delims任何值的,不管他后面有多少空格也是一样,也就是没有任何分隔符,所以全部显示
第二条语句因为delims选项是最后一个,他们是以双引号为结束标识符的,所以是以空格为分隔符的,所以我们现在还无法以把双引号做为
delims选项的值。
-----------------------------以下為繁體xp自身For命令幫助----------------------------
C:/>for /?
對一組檔案中的每個檔案執行指定的命令。
FOR %variable IN (set) DO 命令 [command-parameters]
%variable 指定一個可以取代的參數。
(set) 指定由一或多個檔案組成的檔案組。您可使用通配字元。
command 指定命令來執行每一個檔案。
command-parameters
為所指定的命令指定變數或參數。
如果要在批次程式中使用 FOR 命令,請指定 %%variable,而不要指定
%variable。 變數名稱有大小寫的區分,所以 %i 不同於 %I。
如果您啟用擴充命令,則額外支援下列的 FOR 命令
格式:
FOR /D %variable IN (set) DO command [command-parameters]
如果 set 中包含萬用字元,則指定與目錄
名稱相符,而不是與檔案名稱相符。
FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
在樹狀目錄中切換 [drive:]路徑,並於樹狀目錄的每一個目錄下執行
FOR 陳述式。如果未在 /R 之後指定目錄規格,則採用目前的目錄。
如果 set 只是單一句點 (.) 字元,則它只會列舉樹狀目錄結構。
FOR /L %variable IN (start,step,end) DO command [command-parameters]
set 是從開頭到結尾一次跳一步的連續數字。所以 (1,1,5) 會產生
連續值 (1 2 3 4 5) 而 (5,-1,1) 會產生連續值 (5 4 3 2 1)
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]
filenameset 可以是一個以上的檔案名稱。每個檔案都已開啟,
讀取及處理過,才繼續進行下個檔案名稱組。處理檔案讀取的一致
性,將它分成獨立的文字行,然後將每一行分析成零或更多的字串。
用已找到的字串值為變數值,來呼叫 For 迴圈的內容。預設狀態,
/F 傳出每個檔案的每一行中,以空格分隔的第一個字串。空白行
會被略過。您可以指定 "options" 參數來覆寫預設的分析行為。
這是有引號的字串,包含一個以上的關鍵字,來指定不同的分析
選項。關鍵字是:
eol=c - 指定一個行尾註解字元
(只有一個)
skip=n - 指定在檔案開頭要掠過的
行數。
delims=xxx - 指定分隔符號的集合。 這會取代
預設的空白與定位字元的分隔符號集合。
tokens=x,y,m-n - 指定每一行的哪些文字串應該被
傳到 for 的內部以用來進行每一個重複操作。
這會導致額外的變數名稱被配置。
m-n 格式代表一個範圍,
指定了第 m 個到第 n 個字串項。
如果在 tokens= 字串的最後一個字元是
星號,則會配置一個額外的變數
來接收最後一個字串項被分析後
的其他文字。
usebackq - 指定新語義開始作用。
其中反括號的字串會被當作命令來執行,
而單引號字串是純文字字串。
此外還允許使用雙引號來
引用在 filenameset 內
的檔名。
以下是一個範例:
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k
這會分析 myfile.txt 檔案中的每一行,它不會去管以分號開頭的行數
,直接將第 2 個及第 3 個語法從每一行傳到 for 主體,而其語法是
用逗號和/或空格分開的。請注意,for 主體陳述式參照 %i 以取得第
二個語法,參照 %j 以取得第三個語法,使用 %k 取得第三個語法之
後的剩餘字串。因為檔案名稱含有空格,您必須用雙引號來括住檔案名
稱。要這樣使用雙引號,您必須使用 usebackq 參數。否則雙引號會被
解譯成用來定義一般文字。
使用 %i 明白地在 for 陳述式中宣告,並透過 tokens= option 使用
%j 作暗式性的宣告。您可以藉由 tokens= line 來指定最多 26 個語
法,前提是它宣告的變數不能高於字母 'z' 或 'Z'。請記住,FOR 變
數是單一字元的,同時在任一時間內,您不能同時使用超過 52 個 FOR
變數。
您也可以使用 FOR /F 命令在立即字串中分析邏輯,方法是將括弧之間的
filenameset 變成一個引號字串。它會被視為從檔案輸入的單行,並加
以分析。
最後,您可以使用 FOR /F 命令來分析一個命令的輸出。方法是將括弧
內的 filenameset 變成單引號字串。它將被視為一個命令列,這個命令
行將會傳到子 CMD.EXE,而輸出將會被擷取到記憶體中,當成檔案來分
析。所以下列的範例:
FOR /F "delims==" %i IN ('set') DO @echo %i
將列舉目前環境中的環境變數名稱。
此外,已經加強了 FOR 變數參考的取代功能。
您現在可以選用下列的語法:
%~I - 展開 %I 且移除包圍的引號 (")
%~fI - 展開 %I 為一個完全符合的路徑名稱
%~dI - 只展開 %I 為磁碟機代號
%~pI - 只展開 %I 為路徑
%~nI - 只展開 %I 為檔名
%~xI - 只展開 %I 為副檔名
%~sI - 展開的路徑只包含短檔名
%~aI - 展開 %I 為檔案的檔案屬性
%~tI - 展開 %I 為檔案的日期/時間
%~zI - 展開 %I 檔案的長度
%~$PATH:I - 搜尋所有列在 PATH 環境變數內的目錄
且展開 %I 為
第一個找到的完全符合檔名。
如果沒有定義環境變數名稱
或是搜尋找不到檔案,
則這個修飾元會展開為
空字串。
修飾元可以合併使用以獲得綜合的結果:
%~dpI - 只展開 %I 為磁碟機代號與路徑
%~nxI - 只展開 %I 為檔名與副檔名
%~fsI - 只展開 %I 為含短檔名的完全路徑
%~dp$PATH:i - 為 %I 搜尋所有列在 PATH 環境變數內的目錄
且展開第一個找到的項目為磁碟機代號及
路徑。
%~ftzaI - 展開 %I 為像 DIR 一樣的輸出行
在上面的範例中 %I 和 PATH 能用其他的合法值取代。%~ 語法是由合法的
FOR 變數名稱來終止。如果選用像 %I 的大寫名稱可以增加可讀性而且避免
和修飾元的混淆,因為這些並不區分大小寫。