最近由於工作的原因,總是需要些一些命令列下的批次檔,這些副檔名為".bat"的檔案,是從Dos時代一路傳承下來的,所以我們總是喜歡叫他bat檔案。從上大學的時候,一直用bat做一些小的東西,從來沒有感受到過它的威力,最近用它做一些工作,發現這個東西還真的比較有意思。總結一下,希望對大家的工作能有所協助。Bat有傳統的模式,和Command Extensions兩種模式,擴充用法通常是指後者。
最常用的命令:Call,Echo,For,Goto,If,Pause,REM,shift
Call 命令:調用另外的一個批次檔。常用的方式就是:"Call sample.bat",新擴充的一個用法是 "Call :label arguments",也就是說,你可以用Call來調用Bat檔案內部的一段指令碼,用exit來退出當前的call調用。如果配合Goto語句的話,實際上是擴充的Bat檔案支援了一個Ugly的函數。
這裡需要注意的是,Batch指令碼的參數(%0 %1 ...)有了一些新的變化:
%* 表示這個批次檔的所有的參數(%1 %2 ....)
對於每一個%n還有一些擴充:
%~1 刪除%1的兩端的雙引號
%~f1 擴充成%1的全部檔案名稱
%~d1 擷取%1的盤符
%~p1 擷取%1的檔案路徑
%~n1 擷取%1的檔案名稱
%~x1 擷取%1的副檔名
%~s1 擷取短檔案名稱
%~a1 擷取檔案的屬性
%~t1 擷取檔案的時間
%~z1 擷取檔案的大小
%~$PATH:1 從指定的PATH環境變數中尋找%1並且擴充成全檔案名稱
而且上面的還可以組合,例如:
%~dp1 把%1擴充成盤符和路徑
%~nx1 把%1擴充成檔案名稱和副檔名
%~dp$PATH:1 從制定的PATH中搜尋%1,並且擴充成盤符和路徑的形式
%~ftza1 擴充成dir類似的輸出結果,檔案名稱 時間 大小 屬性
echo
用來顯示一段文字,沒有什麼好說的。
goto
用來進行跳轉:
goto END
:END
也沒有什麼好說的。
for 命令:
這個裡面最複雜的一個命令。
基本形式:
for %variable in (set) DO command [command-parameters]
需要注意的是,這裡的variable一定是單個字元的。set可以是一個或者多個檔案,也可以使用萬用字元:
for %f in (*.txt *.log) DO type %f
表示尋找目前的目錄下所有的.txt,.log,在螢幕上列印它的內容。
這裡需要注意的是,Do後面可以加()來執行多行的語句;
for %%f in ( *.txt ) DO (
echo process %%f...
type %%f
)
對於擴充的For語句,有如下的幾種形式:
for /D %variable IN (set) DO command [command-parameters]
對目錄進行操作
for /R [[driver:]path] %varable IN (set) do command [command-parameters]
對一個路徑下的所有的目錄作指定的操作
for /L %variable IN (start,step,end) DO command [command-parameters]
產生一個列表,例如(1,1,5) 則產生一個(1 2 3 4 5)的列表
for /F ["options"] %variable IN (file-set|"string"|'command') DO command [command-parameters]
這個命令分三種情況,第一個是一個檔案的集合,這種情況下,所有的這些檔案都會被開啟,命令將處理檔案的內容。如果IN的括弧裡面是有雙引號的,則是處理這個字串。如果括弧裡面的是單引號的話,則是處理執行命令以後的結果。如果指定了usebackq的話,則單引號表示的是字串,反向的單引號表示執行的命令,這個時候雙引號可以用來把包含空格的路徑括起來。
一個一個的解釋,首先是options,options有如下的選項:
eol=c 只能指定一個字元,以此開始的為注釋行。
skip=n 跳過檔案的n行
delims=xxx 指出分隔字元的結合。預設的是空格和TAB
tokens=x,y,m-n,* 指定擷取的Token.
usebackq 使用反單引號(~鍵一起的那個)
例如:
for /F "eol=; token=2,3* delims=, " %i IN ( myfile.txt ) do @echo %i %j %k
解析myfile.txt,忽略分號開始的行,%i是第二個,%j是第三個,%k是剩下的所有。
這裡需要注意的是,上面%~進行擴充的那些東西,對於FOR迴圈中的檔案變數也是有效。
for %Z in (*.txt) do (
echo %~fZ
)
上面的命令就是用來顯示全路徑名的。
IF命令:
IF命令以供有三種形式:
IF [NOT] ERRORLEVEL number command
IF [NOT] string1 == string2 command
IF [NOT] exists file command
非常簡單,沒有什麼好說的,擴充的命令如下:
IF [/I] string1 compare-op string2 command
IF CMDEXTVERSION number command
IF DEFINED variable command
比較操作符如下:
EQU,NEQ,LESS,LEQ,GTR,GEQ,不多說了,很簡單。
/I標誌增加的時候,忽略大小寫。
CMDEXTVERSION有點像ERRORLEVEL,不同的是他和Commend Extensions的內部數字作比較。
DEFINED用來判斷一個環境變數是不是被定義。
可以用%ERRORLEVEL%,%CMDEXTVERSION%,%CMDCMDLINE%作變數用,前面兩個很好理解,最後一個就是輸入的命令列。
注意IF ERRORLEVEL命令,這個判斷的是上一個命令的結果,所以一定按照ERRORLEVEL從大到小的順序進行判斷。
Pause命令:
讓程式停下來等按鍵,沒有什麼好說的。
REM命令,注釋,僅此而已
shift命令:
shift /2
修改參數的位置,從第二個參數開始,把後面的一個參數超前挪動一位。%3=>%2,%4=>%3,%0,%1不變。
Choice命令:
提示使用者作出選擇的命令;支援如下的參數
/C XNC 給出X,N,C三個選擇
/N 隱藏提示資訊
/CS 支援大小寫
/T 10 10秒逾時
/D 預設選擇
/M text 提示資訊
字串操作:
操作方法一,用FOR命令來進行操作。
操作方法二,%variable:~start,length%從變數中截取字串。%variable:replace=candicate%來替換字串。
set操作:
設定變數,可選的參數是:
/A 用來進行數學運算,支援與C語言一樣的操作符
/P 根據使用者的輸入來設定環境變數
運算式運算:
調用expr來運算。
還可以set /a進行
其他的注意事項:
在寫Bat檔案的時候,一定要注意在開始和結束的時候setlocal enabledelayedexpansion/endlocal這樣你改變的環境不會影響到外面。
最容易出錯的地方:
錯誤的方法:
for ...... do (
set /a index+=1
use .... %index% ...
)
這裡所有的%index%都是初始值,而不是你想要的。
下面的才是正確的:
for ...... do (
set /a index+=1
use ... !index!...
)