1. 程式人生 > >Window批處理命令學習筆記

Window批處理命令學習筆記


批處理檔案是無格式的文字檔案,本質就是一堆DOS命令按一定順序排列而形成的集合, 它英文譯為BATCH,副檔名為 .bat 或 .cmd。在命令提示下鍵入批處理檔案的名稱,或者雙擊該批處理檔案,系統就會呼叫Cmd.exe按照該檔案中各個命令出現的順序來逐個執行它們。使用批處理檔案(也被稱為批處理程式或指令碼),可以簡化日常或重複性任務。

 

 

 

基礎篇

一. 簡單批處理內部命令簡介

echo、@、call、pause、rem()是批處理檔案最常用的幾個命令,if goto choice for是批處理檔案中比較高階的命令。

 

1.echo


echo 表示顯示此命令後的字元
echo off
表示在此語句後所有執行的命令都不顯示命令列本身
echo [{on|off}] [message]

 

[email protected] 命令
表示不顯示@後面的命令,(只能影響當前行)

Sample:@echo off / echo hello world

 

3.goto命令
指定跳轉到標籤,找到標籤後,程式將處理從下一行開始的命令。
語法:goto label (label是引數,用“:字串”來定義,指定所要轉向的批處理程式中的行,所在行不被執行。)

注意:
(1)
標號前是ASCII字元的冒號":",冒號與標號之間不能有空格。
(2) 標號的命名規則與檔名的命名規則相同。
(3) DOS支援最長八位字元的標號,當無法區別兩個標號時,將跳轉至最近的一個標號。

4.Rem命令小技巧: 用::代替rem)
註釋命令,在C語言中相當與/*--------*/,它並不會被執行,只是起一個註釋的作用,便於別人閱讀和你自己日後修改。

5.Pause命令
暫停,等待按鍵繼續,可用來回顯除錯使用。

 

6.Call命令
從一個批處理程式呼叫另一個批處理程式,並且不終止父批處理程式,執行完子批處理檔案後將返回到父檔案並執行父檔案的後續命令。如果在指令碼或批處理檔案外使用 Call,它將不會在命令列起作用。
語法
call [Drive:][Path] FileName [BatchParameters] [:label [arguments]
引數
[Drive:}[Path] FileName
指定要呼叫的批處理程式的位置和名稱。filename 引數必須具有 .bat 或 .cmd 副檔名。

 

7.start命令
呼叫外部程式,所有的DOS命令和命令列程式都可以由start命令來呼叫。
入侵常用引數:
MIN 開始時視窗最小化
SEPARATE 在分開的空間內開始 16 位 Windows程式
HIGH 在 HIGH 優先順序類別開始應用程式
REALTIME 在 REALTIME 優先順序類別開始應用程式
WAIT 啟動應用程式並等候它結束
parameters 這些為傳送到命令/程式的引數
執行的應用程式是 32-位 GUI 應用程式時,CMD.EXE 不等應用程式終止就返回命令提示。如果在命令指令碼內執行,該新行為則不會發生。


8.choice 命令

choice 使用此命令可以讓使用者輸入一個字元,從而執行不同的命令。使用時應該加/c:引數,c:後應寫提示可輸入的字元,之間無空格。它的返回碼為1234……

(注意:choice命令為DOS或者Windows系統提供的外部命令,不同版本的choice命令語法會稍有不同,請用choice /?檢視用法。)

 

choice的命令語法(該語法為Windows 2003中choice命令的語法,其它版本的choice的命令語法與此大同小異):
CHOICE [/C choices] [/N] [/CS] [/T timeout /D choice] [/M text]
描述:
該工具允許使用者從選擇列表選擇一個專案並返回所選專案的索引。


引數列表:
  /C choices 指定要建立的選項列表。預設列表是 "YN"。
  /N 在提示符中隱藏選項列表。提示前面的訊息得到顯示,選項依舊處於啟用狀態。
  /CS 允許選擇分大小寫的選項。在預設情況下,這個工具是不分大小寫的。
  /T timeout 做出預設選擇之前,暫停的秒數。可接受的值是從 0到 9999。如果指定了                0,就不會有暫停,預設選項會得到選擇。
  /D choice 在nnnn 秒之後指定預設選項。字元必須在用 /C 選項指定的一組選擇中;         同 時,必須用 /T 指定 nnnn。
  /M text 指定提示之前要顯示的訊息。如果沒有指定,工具只顯示提示。
  /? 顯示幫助訊息。

注意:
ERRORLEVEL 環境變數被設定為從選擇集選擇的鍵索引。列出的第一個選擇返回 1,第二個選擇返回 2,等等。如果使用者按的鍵不是有效的選擇,該工具會發出警告響聲。如果該工具檢測到錯誤狀態,它會返回 255 的ERRORLEVEL 值。如果使用者按 Ctrl+Break 或 Ctrl+C 鍵,該工具會返回 0的 ERRORLEVEL 值。在一個批程式中使用 ERRORLEVEL 引數時,將引數降序排列。

示例:
CHOICE /?
CHOICE /C YNC /M "
確認請按 Y,否請按 N,或者取消請按 C。"
CHOICE /T 10 /C ync /CS /D y
CHOICE /C ab /M "選項 1 請選擇a,選項 2 請選擇 b。"
CHOICE /C ab /N /M "選項 1 請選擇 a,選項 2 請選擇 b。"
Sample:
Sample.bat的內容如下:
@echo off
choice /c:dme defrag,mem,end
if errorlevel 3 goto defrag (應先判斷數值最高的錯誤碼)
if errorlevel 2 goto mem
if errotlevel 1 goto end

:defrag
c:dosdefrag
goto end
:mem
mem
goto end
:end
echo good bye

此檔案執行後,將顯示defrag,mem,end[D,M,E]? 使用者可選擇d m e ,然後if語句將作出判斷,d表示執行標號為defrag的程式段,m表示執行標號為mem的程式段,e表示執行標號為end的程式段,每個程式段最後都 以goto end將程式跳到end標號處,然後程式將顯示good bye,檔案結束。

 

9.If命令

if 表示將判斷是否符合規定的條件,從而決定執行不同的命令。 有三種格式:
(1)、if [not] "引數" == "字串"  待執行的命令

如if "%1"=="a" format a:
if {%1}=={} goto :noparms
if {%2}=={} goto :noparms

注意:為了防止引數為空的情況,一般會將字串用雙引號

(2)、if [not] exist 檔名  待執行的命令
如果[沒]有指定的檔案,則條件成立,執行命令,否則執行下一句。
如if exist config.sys edit config.sys如果存在檔案則對其進行編輯

(3)、if errorlevel / if not errorlevel  數字  待執行的命令
如果返回碼等於指定的數字,則條件成立,執行命令,否則執行下一句。
DOS程式執行時都會返回一個數字給DOS,稱為錯誤碼errorlevel或稱返回碼,常見的返回碼為0、1。

 

10.for命令(詳解見進階篇)
for 命令是一個比較複雜的命令,主要用於引數在指定的範圍內迴圈執行命令。
在批處理檔案中使用 FOR 命令時,指定變數請使用%%variable

for{%variable|%%variable} in (set) do command [command-parameters]
%variable 指定一個單一字母可替換的引數。
(set) 指定一個或一組檔案,可以使用萬用字元。
command 指定對每個檔案執行的命令。
command-parameters 為特定命令指定引數或命令列開關。
在批處理檔案中使用 FOR 命令時,指定變數請使用%%variable而不要用 %variable。變數名稱是區分大小寫的,所以 %i 不同於 %I

 

執行機理:for語句依次提取set中的每一個元素,把它的值賦予形式變數variable,帶到do後的command中參與命令的執行;並且每次只提取一個元素,然後執行一次do後的命令語句,而無論這個元素是否被帶到command中參與了command的執行;當執行完一次do後的語句之後,再提 取set中的下一個元素,再執行一次command,如此迴圈,直到set中的所有元素都已經被提取完畢,該for語句才宣告執行結束;

 

 

 

 

 

二.如何在批處理檔案中使用引數

批處理檔案使用引數(相當於DOS命令的命令列引數),需要用到一個引數表示符“%”。
%[1-9]表示引數,引數是指在執行批處理檔案時在檔名後加的以空格(或者Tab)分隔的字串。變數可以從%0到%9,%0表示批處理命令本身,其它引數字串用%1到%9順序表示。當有多個引數時需要用shift來移動,這種情況並不多見,我們就不考慮它了。
例:C:根目錄下有一批處理檔名為f.bat,內容為:
@echo off
format %1

如果執行C:\>f a:
那麼在執行f.bat時,%1就表示a:,這樣format %1就相當於formata:,於是上面的命令執行時實際執行的是format a:

例:C:根目錄下一批處理檔名為t.bat,內容為:
@echo off
type %1
type %2

那麼執行C:\>t a.txt b.txt
%1 : 表示a.txt
%2 : 表示b.txt
於是上面的命令將順序地顯示a.txt和b.txt檔案的內容。

怎麼樣,使用引數還是比較簡單的吧?你這麼帥一定學會了^_^.

 

 

 

 

 

三.如何使用組合命令(Compound Command)

1.&

Usage:第一條命令 & 第二條命令 [& 第三條命令...]

用這種方法可以同時執行多條命令,而不管命令是否執行成功

^ 對特殊符號( > < &)的前導字元

 

2.&&

Usage:第一條命令 && 第二條命令 [&& 第三條命令...]

用這種方法可以同時執行多條命令,當碰到執行出錯的命令後將不執行後面的命令,如果一直沒有出錯則一直執行完所有命令;

Sample:在做備份的時候可能會用到這種命令會比較簡單,如:
dir file://192.168.0.1/database/backup.mdb && copy file://192.168.0.1/database/backup.mdb E:backup
如果遠端伺服器上存在backup.mdb檔案,就執行copy命令,若不存在該檔案則不執行copy命令。這種用法可以替換IF exist了 :)

 

3.||

Usage:第一條命令 || 第二條命令 [||第三條命令...]

用這種方法可以同時執行多條命令,當碰到執行正確的命令後將不執行後面的命令,如果沒有出現正確的命令則一直執行完所有命令;

 

 

 

 

 

四、管道命令的使用

1.| 命令
Usage:第一條命令 | 第二條命令 [| 第三條命令...]
將第一條命令的結果作為第二條命令的引數來使用,記得在unix中這種方式很常見。

sample:
time /t>>D:IP.log
netstat -n -p tcp|find ":3389">>D:IP.log
start Explorer
看出來了麼?用於終端服務允許我們為使用者自定義起始的程式,來實現讓使用者執行下面這個bat,以獲得登入使用者的IP。

 

2.>、>>輸出重定向命令

重定向操作使用重定向操作符將命令輸入和輸出資料流從預設位置重定向到其他位置。輸入或輸出資料流的位置稱為控制代碼。下表列出可用的控制代碼:

控制代碼

控制代碼的數字代號

描述

STDIN

0

鍵盤輸入

STDOUT

1

輸出到命令提示符視窗

STDERR

2

錯誤輸出到命令提示符視窗

UNDEFINED

3-9

控制代碼由應用程式單獨定義,它們是各個工具特有的

數字 0 到 9 代表前 10 個控制代碼。可以使用命令 Cmd.exe 執行程式,並對該程式前 10 個控制代碼中的任何一個控制代碼進行重定向。要指定要用的控制代碼,在重定向操作符之前鍵入該控制代碼的數字。如果未定義控制代碼,則預設的 < 重定向輸入操作符是 0,而預設的 > 重定向輸出操作符是 1。鍵入< 或 > 操作符之後,必須指定資料的讀寫位置。可以指定檔名或其他現有的控制代碼。要指定重定向到現有控制代碼,請使用與 (&) 字元,後面接要重定向的控制代碼號(即 &控制代碼號)。例如,下面的命令可以將控制代碼 2(即 STDERR)重定向到控制代碼 1(即 STDOUT):2>&1


將一條命令或某個程式輸出結果的重定向到特定檔案中, > 與 >>的區別在於,>會清除調原有檔案中的內容後寫入指定檔案,而>>只會追加內容到指定檔案中,而不會改動其中的內容。

sample1:
echo hello world>c:hello.txt (stupid example?)

sample2:

 

3.< 、>& 、<&  (不常用)
< 從檔案中而不是從鍵盤中讀入命令輸入。
>& 將一個控制代碼的輸出寫入到另一個控制代碼的輸入中。
<& 從一個控制代碼讀取輸入並將其寫入到另一個控制代碼輸出中。

 

 


rmdir /S /Q %mhnet% 2>NUL 1>NUL 做簡單解釋。這句程式碼的大意是指將 %mhnet% 指定的目錄刪除,/s 代表刪除其中的子目錄, /q 表示刪除目錄樹時不提示確認, 1>nul 表示將正確刪除目錄樹的資訊禁止輸出,2>nul 表示將刪除過程中的錯誤資訊禁止輸出。


 

 

 

 

進階篇

FOR命令詳解

對所有的批處理初學者來說,for的應用是最難理解以及掌握的。在批處理中,for是最為強大的命令語句,它的出現,使得解析文字內容、遍歷檔案路徑、數值遞增/遞減等操作成為可能;配合if、call、goto等流程控制語句,更是可以實現指令碼複雜的自動化、智慧化操作;合理使用for語句,還能使程式碼大為簡化,免除各位編寫大量重複語句之苦,而能否熟練使用 for語句,已經成為衡量一個人批處理水平高低最主要的標準。本章節由淺入深,為大家專門講解for的用法。

for語句的基本用法
正如色彩繽紛的七彩光芒是由紅綠藍三原色構成的一樣,最複雜的for語句,也有其基本形態,它的模樣是這樣的:
在cmd視窗中:
for %I in (command1) do command2

在批處理檔案中:
for %%I in (command1) do command2

之所以要區分cmd視窗和批處理檔案兩種環境,是因為在這兩種環境下,命令語句表現出來的行為雖然基本一樣,但是在細節上還是稍有不同,最明顯的一個差 異就是:在cmd視窗中,for之後的形式變數I必須使用單百分號引用,即%I;而在批處理檔案中,引用形式變數I必須使用雙百分號,即%%I。為了方便起見,若不是特別強調,以下的講解都以批處理檔案環境為例。

我們先來看一下for語句的基本要素都有些什麼: 引用:
1、for、in和do是for語句的關鍵字,它們三個缺一不可;
2、%%I是for語句中對形式變數的引用,就算它在do後的語句中沒有參與語句的執行,也是必須出現的;
3、in之後,do之前的括號不能省略;
4、command1表示字串或變數,command2表示字串、變數或命令語句;現在,你可能已經會寫一個簡單的for語句了:
[example]

@echo off
for %%I in (bbs.bathome.cn) do echo %%I
pause

儲存為批處理檔案並執行,將會在彈出的批處理視窗中看到這樣的資訊:
bbs.bathome.cn
請按任意鍵繼續...很快地,你會覺得這個for語句是如此的簡單,簡單到你絲毫感受不出它的強大:這個for語句,和我直接用echo語句沒什麼兩樣啊!

是的,演示程式碼永遠都只是演示而已,就像大多數高階語言的教科書一樣,在引導新手學習的時候,基本上都是千篇一律地告訴大家如何編寫一個能顯示 hello world! 的視窗,從這些演示程式碼中,你看不到它們具有多少實用性,你只是感到有點好奇:咦,居然彈出了一個視窗?片刻之後,你就會覺得索然無味。

那好吧,為了讓大家對for更加感興趣,我們先來分析一下for語句的一些注意事項,之後,再讓大家看看更為強大的for語句例項。


1、 for語句的形式變數I,可以換成26個字母中的任意一個,這些字母會區分大小寫,也就是說,%%I和%%i會被認為不是同一個變數;形式變數I還可以換 成其他的字元,但是,為了不與批處理中的%0~%9這10個形式變數發生衝突,請不要隨意把%%I替換為%%0 ~%%9中的任意一個;
2、in和do之間的command1表示的字串或變數可以是一個,也可以是多個,每一個字串或變數,我們稱之為一個元素,每個元素之間,用空格鍵、跳格鍵、逗號或等號分隔;
3、for語句依次提取command1中的每一個元素,把它的值賦予形式變數I,帶到do後的command2中參與命令的執行;並且每次只提取一 個元素,然後執行一次do後的命令語句,而無論這個元素是否被帶到command2中參與了command2的執行;當執行完一次do後的語句之後,再提 取command1中的下一個元素,再執行一次command2,如此迴圈,直到command1中的所有元素都已經被提取完畢,該for語句才宣告執行 結束;其中,第3點是最為關鍵的,它描述了for語句的執行過程,是for語句的精髓所在,大家一定要牢記這一條,才能深刻理解更為複雜的for流程。

有了以上的基礎,我們再來看一個例子,這個例子修改了example1的部分內容,結果將大不一樣:
[example2]
程式碼:

@echo off
for %%I in (bbs,bathome,cn) do echo %%I
pause

和example1的執行結果相比,example2發生瞭如下變化:

1、顯示結果分成了3行(不算最後一行中文提示);
2、每一行都從逗號處被切分;

如果把 bbs.bathome.cn 這個字串中的點號換為空格、跳格或等號,執行結果將和example2的執行結果別無二致。

現在,我們來分析一下example2程式碼中for語句的執行過程:

首先,for語句以逗號為分隔符,把 bbs,bathome,cn 這個字串切分成三個元素:bbs、bathome和cn,由此決定了do後的語句將會被執行3次;
然後,第一次執行過程是這樣的:先把 bbs 這個字串作為形式變數I的值,帶入do後的語句中加以執行,也就是執行 echo %%I 語句,此時的I值為bbs,因此,第一次執行的結果,將會在螢幕上顯示bbs這個字串;第二次執行和第一次執行的過程是一樣的,只不過此時I的值已經被替換為command1中的第二個元素了,也就是 bathome 這個字串;如此迴圈,當第三次echo執行完畢之後,整條for語句才算執行完畢,此時,將執行下一條語句,也就是pause命令。

其實,這個例子只比上一個例子多了一點花樣,有趣了那麼一點點:一條for語句的執行結果居然被分成了3行!



應該明確的是,for不是一個簡單的命令,它的用法比較複雜,它還可以帶四個引數(/L /D /R /F),其中:/L和/F引數是最經常用到的。當然,它本身也可以不帶引數,下面我們通過具體的例子來講解for的運用。

一、不帶引數的for:

@echo off
for %%i in (1 2 3 4 5) do echo %%i
pause

將以上程式碼儲存為批處理檔案(如何儲存?),然後執行,可以發現螢幕上顯示1 2 3 4 5(每字一行)
是不是明白了一些?它的整個執行機制我們可以這樣看:for不停的從括號中拿出5個“東西”來(以空格做間隔),並將這5個“東西”依次傳給臨時變數%%i,同時把這個變數echo出來....

從這個例子我們可以看出,for的基本用法是:
for 變數 in (目標) do 幹什麼?

變數常用%%i 來表示,當然也可以換成%%j;目標就是待處理的物件集合,比如這裡的1 2 3 4 5;這裡的幹什麼的內容為:批處理命令。

二、帶引數 /L 的for (這裡的 引數/L 可以理解為 "list" 的意思,代表一個數列)

FOR /L %variableIN (start,step,end) DO command [command-parameters] 該集表示以增量形式從開始到結束的一個數字序列。

 

@echo off
for /l %%i in (1 1 5) do echo %%i
pause

顯示結果也為:1 2 3 4 5(每字一行)
它的意思和上面的意思差不多,但是括號中的物件卻不需要 寫成 1 2 3 45 的形式了,而是:1 1 5,因為它啟用了引數 /L ,就是告訴for,這個括號裡的物件是個數列,怎樣的數列?就是以 1 開始,步長 為1 ,結束值為5的一個等差數列,再舉個例項:
::顯示 從 10 - 20 的所有偶數:

@echo off
for /l %%i in (10 2 20) do echo %%i
pause

 

三、for的 /D 和/R 引數(這兩個引數個人比較少用)
1>/D引數(常用來查詢 當前目錄 或者 指定目錄的資料夾)
基本用法:FOR /D%variable IN (set) DO command [command-parameters]  如果集中包含萬用字元,則指定與目錄名匹配,而不與檔名匹配。
如:查詢F盤根目錄下的資料夾

FOR /R [drive:]path] %variable IN (set) DO command [command-parameters] 檢查以 [drive:]path 為根的目錄樹,指向每個目錄中的FOR 語句。如果在 /R 後沒有指定目錄,則使用當前目錄。如果集僅為一個單點(.)字元,則列舉該目錄樹。

@echo off
for /d %%i in (f:\*) do echo %%i
pause>nul

如果省略 括號中的 "f:\",則會直接查詢 批處理 所在目錄的資料夾
假設 本批處理檔案 儲存在:F:\test下
執行以下批處理程式碼,將會查詢 F:\test下的資料夾
程式碼:

@echo off
for /d %%i in (*) do echo %%i
pause>nul2>


/r引數
基本用法:FOR /R[[drive:]path] %variable IN (set) DO command [command-parameters]
檢查以[drive:]path 為根的目錄樹中,所有符合(set)的檔案或者資料夾。如果在 /R 後沒有指定目錄,則使用當前目錄。如果集僅為一個單點(.)字元,則列舉該目錄樹。
用法示例:
列舉F:盤下所有的檔案
程式碼:

@echo off
for /r f:\ %%i in (*) do echo %%i
pause>nul

列舉F:盤下所有的 .bat檔案(包括子目錄),則:
程式碼:

@echo off
for /r f:\ %%i in (*.bat) do echo %%i
pause>nul

如果省略以上程式碼中的F:\,則會列舉當前目錄所有符合(set)的檔案
如:列舉批處理所在目錄的 所有 批處理檔案(包括子目錄)
程式碼:

@echo off
for /r %%i in (*.bat) do echo %%i
pause>nul

 

四、帶引數 /f 的for(這裡的引數/F可以理解為“file”的意思,程式碼處理物件為文字串)
for /f 引數最為複雜,難懂和常用.
在剛學時確實費了我不少腦筋,下面就我個人的理解,給新手們通俗的講講,也好讓新手少走些彎路.

 

以預設方式,/F 通過每個檔案的每一行中分開的第一個空白符號。跳過空白行。可通過指定可選"options"引數替代預設解析操作。這個帶引號的字串包括一個或多個指定不同解析選項的關鍵字:

eol=c - 指一個行註釋字元的結尾(就一個)
skip=n - 指在檔案開始時忽略的行數。
delims=xxx - 指分隔符集,替換空格和跳格鍵的預設分隔符集。(常用命令)
tokens=x,y,m-n - 指每行的哪一個符號被傳遞到每個迭代的 for 本身。這會導致額外變數名稱的格式為一個範圍。通過 nth 符號指定 m符號字串中的最後一個字元星號,那麼額外的變數將在最後一個符號解析之分配並接受行的保留文字。
usebackq - 指定新語法已在下列情況中使用:在作為命令執行一個後引號的字串並且引號字元為文字字串命令並允許在 fi中使用雙引號擴起檔名稱。
例一:

for /f"skip=1 tokens=1,2* delims= " %%a in (a.txt) do echo %%a %%b %%c
pause

先從引號內的東西講起,很多新手對這些難以理解,因為 for /? 翻譯的簡直是一塌糊塗.
skip=
tokens=
delims=
這三項是用的最多的,根據需要.可以不用,可以一起使用,也可以只使用一個或兩個.
但是不管使用幾個都要用引號將它們擴起來.當然不使用時,自然就不需要引號了.
skip=
for迴圈文字內容是以行為單位,從上至下進行的,skip=1意識就是跳過文字的第一行,即不迴圈第一行
那麼skip=2 自然就是跳過前兩行了,依次類推.........
delims=
先講這句
delims=後面的字元的意識是,將文字每一行的內容以delims=後面的字元分割成若干列.
假設a.txt某一行的內容是 111,222.333 444/555
我們用下面的語句

例二:

for /f"tokens=1-5 delims=,./ " %%a in (a.txt) do echo %%a %%b %%c %%d %%e
pause

顯示結果是 111 222 333 444 555
 意思就是把111,222.333444/555以,./和空格(不分先後)分成了5列.注意程式碼中/和"後面有個空格,使用中要注意空格要放到最後,如"delims=,. /" 這樣就不行了.那如果我們不使用逗號來分割會如何呢?如: "delims=./ "那麼就會分割成111,222 333 444 555  看出區別了嗎?delims=後面可以是多個字元,可以是空格,也可以什麼都沒有,什麼都沒有代表什麼呢?就是不以任何東西為分割符,也是整行的內容了,因為for預設是以,;和空格作分割符的,所以一般要取得整行內容通常會用"delims="這樣的形式來取消for的預設分割符。
tokens=
tokens=1-5
1-5很好理解就1至5,前面我們用delims=後面的字元為分割符,將文字內容分成了多列,那麼你需要的是哪些列呢?用tokens=可以很好幫你提取到。
還是以例二為例:
通過dilims=,./  將文字分成了111 222333 444 555 五列.
注意程式碼中前面有個%%a 這裡的%%a就是代表第一列,第二列就是%%b,第三列就是%%c 依此類推.....
那麼我們如果把echo %%a %%b %%c %%d %%e 改為 echo %%e %%d %%c %%b %%a 會如何呢?
當然.會顯示 555 444 333 222 111
如果是:echo %%b%%d 又會顯示什麼呢?   不用我說了吧!
若是第一個%%a把它改為%%i也是一樣,那麼第二列就是%%j...%%k...依此類推....
明白了?就是按英文字母的順序依此類推的.
這裡我們用的是tokens=1-5但是在例一中,我們用的是tokens=1,2*有什麼區別呢?
其實差不多-號代表從幾至幾而逗號代表單一的,如 tokens=1,5就是代表第一列和第五列,而不是1至5列.
*號代表剩下的所有的列.如:tokens=1,2*代表%%a為第一列,%%b為第二列,%%c代表後面所有的列.
for /f 不但可以迴圈文字內容還可以迴圈字元竄,如:

例三:
程式碼:

for /f"tokens=1-3 delims=,./ " %%a in ("111,222.333 444/555") doecho %%a %%b %%c
pause

只要將()裡的字串用引號擴起來,for就會把它當字串來迴圈,而不是文字.

sample1:
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do command

會分析 myfile.txt 中的每一行,忽略以分號打頭的那些行,將每行中的第二個和第三個符號傳遞給 for 程式體;用逗號和/或空格定界符號。請注意,這個 for 程式體的語句引用 %i 來取得第二個符號,引用 %j 來取得第三個符號,引用 %k來取得第三個符號後的所有剩餘符號。對於帶有空格的檔名,您需要用雙引號將檔名括起來。為了用這種方式來使用雙引號,您還需要使用 usebackq 選項,否則,雙引號會被理解成是用作定義某個要分析的字串的。

%i 專門在 for 語句中得到說明,%j和 %k 是通過tokens= 選項專門得到說明的。您可以通過 tokens= 一行指定最多 26 個符號,只要不試圖說明一個高於字母 ''z'' 或''Z'' 的變數。請記住,FOR 變數是單一字母、分大小寫和全域性的;同時不能有 52 個以上都在使用中。

您還可以在相鄰字串上使用FOR /F 分析邏輯;方法是,用單引號將括號之間的 filenameset 括起來。這樣,該字串會被當作一個檔案中的一個單一輸入行。

最後,您可以用 FOR /F 命令來分析命令的輸出。方法是,將括號之間的 filenameset 變成一個反括字串。該字串會被當作命令列,傳遞到一個子CMD.EXE,其輸出會被抓進記憶體,並被當作檔案分析。因此,以下例子:

FOR /F"usebackq delims==" %i IN (`set`) DO @echo %i

會列舉當前環境中的環境變數名稱。

另外,FOR 變數參照的替換已被增強。

 

 

 

為了讓大家見識一下for的真正威力,本人絞盡腦汁,翻帖無數,不得要領,萬般無奈之下,只好亮出了塵封在箱底多年的一段程式碼:檢測當前硬碟都有哪些分割槽^_^
[example3]
程式碼:

@echo off
set str=c d e f g h i j k l m n o p q r s t u v w x y z
echo
當前硬碟的分割槽有:
for %%i in (%str%) do if exist %%i: echo %%i:
pause

這段程式碼能檢測硬碟都有哪些分割槽,包括U盤和行動硬碟的分割槽,但是,當光碟機中有盤的時候,也會被列出來,這是本程式碼的一個缺憾,在以後的講解中,我將向大家講述如何消除這個瑕疵,敬請關注本系列的後續章節。

 

 

 

 

 

 

命令大全篇


1 echo
@
#關閉單行回顯
echo off
#從下一行開始關閉回顯
@echo off
#從本行開始關閉回顯。一般批處理第一行都是這個
echo on
#從下一行開始打開回顯
echo
#顯示當前是 echo off 狀態還是 echo on 狀態
echo.
#輸出一個回車換行,空白行
      #(echo, echo; echo+ echo[ echo] echo/ echo\)

2 errorlevel
echo %errorlevel%
每個命令執行結束,可以用這個命令列格式檢視返回碼
預設值為0,一般命令執行出錯會設 errorlevel 1


3 dir
dir
  #顯示當前目錄中的檔案和子目錄
dir /a
           #顯示當前目錄中的檔案和子目錄,包括隱藏檔案和系統檔案
dir c: /a:d
#顯示 C 盤當前目錄中的目錄
dir c: /a:-d
#顯示 C 盤根目錄中的檔案
dir c:\ /b/p
#/b只顯示檔名,/p分頁顯示
dir *.exe /s
#顯示當前目錄和子目錄裡所有的.exe檔案


4 cd
cd\
#進入根目錄
cd
#顯示當前目錄
cd /d d:\sdk
#可以同時更改碟符和目錄


5 md
md d:\a\b\c
#如果 d:\a 不存在,將會自動建立中級目錄
#
如果命令副檔名被停用,則需要鍵入 mkdir \a\b\c

6 rd
rd abc
#刪除當前目錄裡的 abc 子目錄,要求為空目錄
rd /s/q d:\temp
#刪除 d:\temp 資料夾及其子資料夾和檔案,/q安靜模式


7 del
del d:\test.txt
#刪除指定檔案,不能是隱藏、系統、只讀檔案
del /q/a/f d:\temp\*.*
刪除 d:\temp 資料夾裡面的所有檔案,包括隱藏、只讀、系統檔案,不包括子目錄
del /q/a/f/s d:\temp\*.*
刪除 d:\temp 及子資料夾裡面的所有檔案,包括隱藏、只讀、系統檔案,不包括子目錄

rd刪除資料夾
del刪除檔案
當資料夾裡有檔案的時候,可以用rd /s 命令把資料夾和裡面的檔案一塊刪掉
而del只能刪除檔案,不能刪除資料夾


8 ren

ren d:\temp tmp #支援對資料夾的重新命名


9 cls
清屏


10 type
顯示檔案內容
type c:\boot.ini
#顯示指定檔案的內容,程式檔案一般會顯示亂碼
type *.txt
#顯示當前目錄裡所有.txt檔案的內容


11 copy
拷貝檔案
copy c:\test.txt d:\test.bak
複製 c:\test.txt 檔案到 d:\ ,並重命名為 test.bak
copy con test.txt
從螢幕上等待輸入,按 Ctrl+Z 結束輸入,輸入內容存為test.txt檔案
con
代表螢幕,prn代表印表機,nul代表空裝置
copy 1.txt + 2.txt 3.txt
合併 1.txt 2.txt 的內容,儲存為 3.txt 檔案
如果不指定 3.txt ,則儲存到 1.txt
copy test.txt +
複製檔案到自己,實際上是修改了檔案日期


12 title
設定cmd視窗的標題
title
新標題          #可以看到cmd視窗的標題欄變了


13 ver
顯示系統版本


14 label
vol
設定卷標
vol
#顯示卷標
label
#顯示卷標,同時提示輸入新卷標
label c:system
#設定C盤的卷標為 system


15 pause
暫停命令


16 rem
::
註釋命令
註釋行不執行操作


17 date
time
日期和時間
date
#顯示當前日期,並提示輸入新日期,按\"回車\"略過輸入
date/t
#只顯示當前日期,不提示輸入新日期
time
#顯示當前時間,並提示輸入新時間,按\"回車\"略過輸入
time/t
#只顯示當前時間,不提示輸入新時間


18 goto
:
跳轉命令
:label
#行首為:表示該行是標籤行,標籤行不執行操作
goto label
      #跳轉到指定的標籤那一行


19 find (
外部命令)
查詢命令
find \"abc\" c:\test.txt
c:\test.txt 檔案裡查詢含 abc 字串的行
如果找不到,將設 errorlevel 返回碼為1
find /i “abc” c:\test.txt
查詢含 abc 的行,忽略大小寫
find /c \"abc\" c:\test.txt
顯示含 abc 的行的行數


20 more (
外部命令)
逐屏顯示
more c:\test.txt
#逐屏顯示 c:\test.txt 的檔案內容


21 tree
顯示目錄結構
tree d:\
#顯示D盤的檔案目錄結構


22 &
順序執行多條命令,而不管命令是否執行成功


23 &&
順序執行多條命令,當碰到執行出錯的命令後將不執行後面的命令
find \"ok\" c:\test.txt && echo
成功
如果找到了\"ok\"字樣,就顯示\"成功\",找不到就不顯示


24 ||
順序執行多條命令,當碰到執行正確的命令後將不執行後面的命令
find \"ok\" c:\test.txt || echo
不成功
如果找不到\"ok\"字樣,就顯示\"不成功\",找到了就不顯示

25 |
管道命令
dir *.* /s/a | find /c \".exe\"
管道命令表示先執行 dir 命令,對其輸出的結果執行後面的 find 命令
該命令列結果:輸出當前資料夾及所有子資料夾裡的.exe檔案的個數
type c:\test.txt|more
這個和 more c:\test.txt 的效果是一樣的


26 >
>>
輸出重定向命令
>
清除檔案中原有的內容後再寫入
>>
追加內容到檔案末尾,而不會清除原有的內容
主要將本來顯示在螢幕上的內容輸出到指定檔案中
指定檔案如果不存在,則自動生成該檔案
type c:\test.txt >prn
螢幕上不顯示檔案內容,轉向輸出到印表機
echo hello world>con
在螢幕上顯示hello world,實際上所有輸出都是預設 >con
copy c:\test.txt f: >nul
拷貝檔案,並且不顯示\"檔案複製成功\"的提示資訊,但如果f盤不存在,還是會顯示出錯資訊
copy c:\test.txt f: >nul 2>nul
不顯示檔案複製成功的提示資訊,並且f盤不存在的話,也不顯示錯誤提示資訊
echo ^^W ^> ^W>c:\test.txt
生成的檔案內容為 ^W > W
^
> 是控制命令,要把它們輸出到檔案,必須在前面加個 ^ 符號

27 <
從檔案中獲得輸入資訊,而不是從螢幕上
一般用於 date time label 等需要等待輸入的命令
@echo off
echo 2005-05-01>temp.txt
date del temp.txt
這樣就可以不等待輸入直接修改當前日期


28 %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %*
命令列傳遞給批處理的引數
%0
批處理檔案本身
%1
第一個引數
%9
第九個引數
%*
從第一個引數開始的所有引數

批引數(%n)的替代已被增強。您可以使用以下語法:

%~1 - 刪除引號(\"),擴充 %1
%~f1 - %1 擴充到一個完全合格的路徑名
%~d1 - 僅將 %1 擴充到一個驅動器號
%~p1 - 僅將 %1 擴充到一個路徑
%~n1 - 僅將 %1 擴充到一個檔名
%~x1 - 僅將 %1 擴充到一個副檔名
%~s1 - 擴充的路徑指含有短名
%~a1 - %1 擴充到檔案屬性
%~t1 - %1 擴充到檔案的日期/時間
%~z1 - %1 擴充到檔案的大小
%~$PATH : 1 - 查詢列在 PATH 環境變數的目錄,並將 %1
擴充到找到的第一個完全合格的名稱。如果環境
變數名未被定義,或者沒有找到檔案,此組合鍵會
擴充到空字串

可以組合修定符來取得多重結果:

%~dp1 - 只將 %1 擴充套件到驅動器號和路徑
%~nx1 - 只將 %1 擴充套件到檔名和副檔名
%~dp$PATH:1 - 在列在 PATH 環境變數中的目錄裡查詢 %1
並擴充套件到找到的第一個檔案的驅動器號和路徑。
%~ftza1 - %1 擴充套件到類似 DIR 的輸出行。
可以參照 call/? for/? 看出每個引數的含意
echo load \"%%1\" \"%%2\">c:\test.txt
生成的檔案內容為 load \"%1\" \"%2\"
批處理檔案裡,用這個格式把命令列引數輸出到檔案


29 if
判斷命令
if \"%1\"==\"/a\" echo
第一個引數是/a
if /i \"%1\" equ \"/a\" echo
第一個引數是/a
/i
表示不區分大小寫,equ == 是一樣的,其它運算子參見 if/?
if exist c:\test.bat echo
存在c:\test.bat檔案
if not exist c:\windows (
echo 不存在c:\windows資料夾
)
if exist c:\test.bat (
echo 存在c:\test.bat
) else (
echo 不存在c:\test.bat
)


30 setlocal
endlocal
設定命令副檔名延緩環境變數擴充
SETLOCAL ENABLEEXTENSIONS
#啟用\"命令副檔名\"
SETLOCAL DISABLEEXTENSIONS
#停用\"命令副檔名\"
SETLOCAL ENABLEDELAYEDEXPANSION
   #啟用\"延緩環境變數擴充\"
SETLOCAL DISABLEDELAYEDEXPANSION
#停用\"延緩環境變數擴充\"
ENDLOCAL
#恢復到使用SETLOCAL語句以前的狀態
命令副檔名預設為啟用
延緩環境變數擴充預設為停用
批處理結束系統會自動恢復預設值
可以修改登錄檔以禁用\"命令副檔名\",詳見 cmd /? 。所以用到\"命令副檔名\"的程
序,建議在開頭和結尾加上 SETLOCAL ENABLEEXTENSIONS ENDLOCAL 語句,以確
保程式能在其它系統上正確執行
\"
延緩環境變數擴充\"主要用於 if for 的符合語句,在 set 的說明裡有其實用例程


31 set
設定變數
引用變數可在變數名前後加 % ,即 %變數名%
set
#顯示目前所有可用的變數,包括系統變數和自定義的變數
echo %SystemDrive%
#顯示系統盤碟符。系統變數可以直接引用
set p
#顯示所有以p開頭的變數,要是一個也沒有就設errorlevel=1
set p=aa1bb1aa2bb2
#設定變數p,並賦值為 = 後面的字串,即aa1bb1aa2bb2
echo %p%
#顯示變數p代表的字串,即aa1bb1aa2bb2
echo %p:~6%
#顯示變數p中第6個字元以後的所有字元,即aa2bb2
echo %p:~6,3%
#顯示第6個字元以後的3個字元,即aa2
echo %p:~0,3%
#顯示前3個字元,即aa1
echo %p:~-2%
#顯示最後面的2個字元,即b2
echo %p:~0,-2%
#顯示除了最後2個字元以外的其它字元,即aa1bb1aa2b
echo %p:aa=c%
#c替換變數p中所有的aa,即顯示c1bb1c2bb2
echo %p:aa=%
#將變數p中的所有aa字串置換為空,即顯示1bb12bb2
echo %p:*bb=c%
#第一個bb及其之前的所有字元被替換為c,即顯示c1aa2bb2
set p=%p:*bb=c%
#設定變數p,賦值為 %p:*bb=c% ,即c1aa2bb2
set /a p=39
#設定p為數值型變數,值為39
set /a p=39/10
#支援運算子,有小數時用去尾法,39/10=3.9,去尾得3p=3
set /a p=p/10
# /a 引數時,在 = 後面的變數可以不加%直接引用
set /a p=”1&0″
#”運算,要加引號。其它支援的運算子參見set/?
set p=
#取消p變數
set /p p=
請輸入
螢幕上顯示請輸入,並會將輸入的字串賦值給變數p
注意這條可以用來取代 choice 命令
注意變數在 if for 的複合語句裡是一次性全部替換的,如
@echo off
set p=aaa
if %p%==aaa (
echo %p%
set p=bbb
echo %p%
)
結果將顯示
aaa
aaa
因為在讀取 if 語句時已經將所有 %p% 替換為aaa
這裡的\"替換\",在 /? 幫助裡就是指\"擴充\"\"環境變數擴充\"
可以啟用延緩環境變數擴充,用 ! 來引用變數,即 !變數名!
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set p=aaa
if %p%==aaa (
echo %p%
set p=bbb
echo !p!
)
ENDLOCAL
結果將顯示
aaa
bbb
還有幾個動態變數,執行 set 看不到
%CD%
#代表當前目錄的字串
%DATE%
#當前日期
%TIME%
#當前時間
%RANDOM%
#隨機整數,介於0~32767
%ERRORLEVEL%
#當前 ERRORLEVEL
%CMDEXTVERSION%
#當前命令處理器副檔名版本號
%CMDCMDLINE%
#呼叫命令處理器的原始命令列
可以用echo命令檢視每個變數值,如 echo %time%
注意 %time% 精確到毫秒,在批處理需要延時處理時可以用到


32 start
批處理中呼叫外部程式的命令,否則等外部程式完成後才繼續執行剩下的指令


33 call
批處理中呼叫另外一個批處理的命令,否則剩下的批處理指令將不會被執行
有時有的應用程式用start調用出錯的,也可以call呼叫


34 choice (
外部命令)
選擇命令
讓使用者輸入一個字元,從而選擇執行不同的命令,返回碼errorlevel1234……
win98
裡是choice.com
win2000pro
裡沒有,可以從win98裡拷過來
win2003
裡是choice.exe
choice /N /C y /T 5 /D y>nul
延時5


35 assoc
ftype
檔案關聯
assoc
設定'副檔名'關聯,關聯到'檔案型別'
ftype
設定'檔案型別'關聯,關聯到'執行程式和引數'
當你雙擊一個.txt檔案時,windows並不是根據.txt直接判斷用 notepad.exe 開啟
而是先判斷.txt屬於 txtfile '檔案型別'
再呼叫 txtfile 關聯的命令列 txtfile=%SystemRoot%\system32\NOTEPAD.EXE%1
可以在\"資料夾選項\"\"檔案型別\"