突然迷上了windows的批處理,突然習慣了在cmd下啟動程式,突然習慣了mkdir,cp,rm.....
禁不住誘惑,用了幾天時間仔細的研究了一下bat的文法結構,主要參照了網上的兩篇word文檔,感覺寫的不錯:
windows_bat命令編寫大全.docx(33kB) windows_BAT批處理命令.doc(175KB)
第一篇word文檔主要介紹批處理中一些很常用的命令的用法,每個命令都很細緻,學完批處理的簡單文法結構之後使用中再看效果會好很多。
第二篇word文檔就講的有點天馬行空了。前1/3部分講的東西簡單易懂,比較適合入門;中間1/3講的比較細緻深入,主要有set,choice,if,for,內建符號的用法,是我關注的重點,進階文法;;最後1/3有一個很龐大的批次程式,用來最佳化xp系統的,基本都是註冊表的操作,對於學習批處理的價值不大,可略過。
可以先拿第二篇的前1/3練手,瞭解基本文法結構,然後可以關注中間1/3部分,強化if,for,choice,set等的使用,這些我感覺真的是批處理裡面的精華部分了,如果在寫自己的批處理的時候遇到不知道怎麼辦的時候,可以看看第一篇word文檔,瀏覽基本命令,大致知道各個命令能做什麼。熟能生巧。
感覺主要是需要知道可以用什麼命令去解決,至於命令的文法不知道,直接查看命令協助就行,協助是最全的文檔。
set:: 定義變數,切割字串,算術運算
for : 字串遍曆,檔案遍曆,迴圈次數控制,切割串
if : 條件判斷
goto: 標籤跳轉
call: bat調用或者label調用
choice: 互動式程式必備
一下內容為個人稍作的總結,以為自己的備忘,個人比較喜歡ue,就直接txt了:
windows bat:
1,echo 表示顯示此命令後的字元
2,echo off 表示在此語句後所有啟動並執行命令都不顯示命令列本身
3,@與echo off相象,但它是加在每個命令列的最前面,表示運行時不顯示這一行的命令列(只能影響當前行)。
4,call 調用另一個批次檔(如果不用call而直接調用別的批次檔,那麼執行完那個批次檔後將無法返回當前檔案並執行當前檔案的後續命令)
5,pause 運行此句會暫停批處理的執行並在螢幕上顯示“Press any key to continue...”或“請按任意鍵繼續。。。”的提示,等待使用者按任意鍵後繼續。
6,rem 表示此命令後的字元為解釋行(注釋),不執行,只是給自己今後參考用的(相當於程式中的注釋)。
Example:
@echo off
rem echo off usage
pause
7,%[1-9]表示參數,參數是指在運行批次檔時在檔案名稱後加的以空格(或者Tab)分隔的字串。變數可以從%0到%9,%0表示批處理命令本身,其它參數字串用%1到%9順序表示。
8,::choice: CHOICE [/C choices] [/N] [/CS] [/T timeout /D choice] [/M text]
/M提示文本,/C選項,/T逾時事件,/D逾時預設選擇
CHOICE /C YNC /M "確認請按 Y,否請按 N,或者取消請按 C"
choice /C dme /M "defrag,mem,end"
if errorlevel 3 goto end
if errorlevel 2 goto mem
if errorlevel 1 goto defrag
9,微軟裡面內建了下列字元不能夠在建立的檔案名稱中間使用
con nul aux \ / | || && ^ > < *
特殊符號,要不""括著,要不加^轉義
> 建立一個檔案
>> 追加到一個檔案後面
, 和空格一樣的預設分隔字元號.
; 注釋,表示後面為注釋
: 標號作用
| 管道操作
用這種方法可以同時執行多條命令,而不管命令是否執行成功
dir c:\*.exe & dir d:\*.exe & dir e:\*.exe
&& Usage:第一條命令 && 第二條命令 [&& 第三條命令...]
當碰到執行出錯的命令後將不執行後面的命令,如果一直沒有出錯則一直執行完所有命令;
|| Usage:第一條命令 || 第二條命令 [|| 第三條命令...]
當碰到執行正確的命令後將不執行後面的命令,如果沒有出現正確的命令則一直執行完所有命令;
10,if語句即可以實現選擇功能。
1、字串比較
if語句僅能夠對兩個字元(串)是否相同、先後順序進行判斷等。其命令格式為:
IF [not] string1 compare-op string2 command1 [else command2]
其中,比較操作符compare-op有以下幾類:
== - 等於
EQU - 等於
NEQ - 不等於
LSS - 小於
LEQ - 小於或等於
GTR - 大於
GEQ - 大於或等於
選擇開關/i則不區分字串大小寫;選擇not項,則對判斷結果進行邏輯非。
字串比較樣本:
===============================================
@echo off
set str1=abcd1233
set str2=ABCD1234
if %str1%==%str2% (echo 字串相同!) else (echo 字串不相同!)
if /i %str1% LSS %str2% (echo str1^<str2) else (echo str1^>=str2)
echo.
set /p choice=是否顯示目前時間?(y/n)
if /i not %choice% EQU n echo 目前時間是:%date% %time%
pause>nul
===============================================
對於最後一個if判斷,當我們輸入n或N時的效果是一樣的,都不會顯示時間。如果我們取消開關/i,則輸入N時,依舊會顯示時間。
另外請注意一下幾個細節:1-echo str1^<str2和echo str1^>=str2;2-echo.。
2、存在判斷
存在判斷的功能是判斷檔案或檔案夾是否存在。其命令格式為:
IF [NOT] EXIST filename command1 [else command2]
===============================================
@echo off
if exist %0 echo 檔案%0是存在的!
if not exist %~df0 (
echo 檔案夾%~df0不存在!
) else echo 檔案夾%~df0存在!
pause>nul
===============================================
這裡注意幾個地方:
1-存在判斷既可以判斷檔案也可以判斷檔案夾;
2-%0即代表該批處理的全稱(包括磁碟機盤符、路徑、檔案名稱和擴充類型);
3-%~df0是對%0的修正,只保留了其磁碟機盤符和路徑,詳情請參考for /?,屬進階批處理範疇;
4-注意if語句的多行書寫,多行書寫要求command1的左括弧必須和if在同一行、else必須和command1的右括弧同行、command2的左括弧必須與else同行、command1和command2都可以有任意多行,即command可以是命令集。
3、定義判斷
定義判斷的功能是判斷變數是否存在,即是否已被定義。其命令格式為:
IF [not] DEFINED variable command1 [else command2]
存在判斷舉例:
===============================================
@echo off
set var=111
if defined var (echo var=%var%) else echo var尚未定義!
set var=
if defined var (echo var=%var%) else echo var尚未定義!
pause>nul
===============================================
對比可知,"set var="可以取消變數,收回變數所佔據的記憶體空間。
11,for
1、無開關
無開關的for語句能夠對設定的範圍內進行迴圈,是最基本的for迴圈語句。其命令格式為:
FOR %%variable IN (set) DO command
其中,%%variable是批次程式裡面的書寫格式,在DOS中書寫為%variable,即只有一個百分比符號(%);set就是需要我們設定的迴圈範圍,類似於C語言裡面的迴圈變數;do後面的command就是迴圈所執行的命令,即迴圈體。
無開關for語句舉例:
===============================================
@echo off
for %%i in (a,"b c",d) do echo %%i
pause>nul
===============================================
2、開關/L
含開關/L的for語句,可以根據set裡面的設定進行迴圈,從而實現對迴圈次數的直接控制。其命令格式為:
FOR /L %%variable IN (start,step,end) DO command
其中,start為開始計數的初始值,step為每次遞增的值,end為結束值。當end小於start時,step需要設定為負數。
含開關/L的for語句舉例(建立5個檔案夾):
===============================================
@echo off
for /l %%i in (1,2,10) do md %%i
pause
===============================================
上例將建立5個檔案夾,檔案夾名稱依次為1、3、5、7、9。可以發現,%%i的結束值並非end的值10,而是不大於end的一個數。
3、開關/F
含開關/F的for語句具有最強大的功能,它能夠對字串進行操作,也能夠對命令的傳回值進行操作,還可以訪問硬碟上的ASCII碼檔案,比如txt文檔等。其命令格式為:
FOR /F ["options"] %%variable IN (set) DO command
其中,set為("string"、'command'、file-set)中的一個;options是(eol=c、skip=n、delims=xxx、tokens=x,y,m-n、usebackq)中的一個或多個的組合。各選項的意義參見for /f。一般情況下,使用較多的是skip、tokens、delims三個選項。
含開關/F的for語句舉例:
===============================================
@echo off
echo **No Options:
for /f %%a in ("1,2,10") do echo a=%%a
echo **Options tokens ^& delims:
for /f "tokens=1-3 delims=," %%a in ("1,2,10") do echo a=%%a b=%%b c=%%c
pause
===============================================
@echo off
echo 本檔案夾裡面的檔案有:
for /f "skip=5 tokens=3* delims= " %%a in ('dir') do (
if not "%%a"=="<DIR>" if not "%%b"=="位元組" if not "%%b"=="可用位元組" echo %%b
)
pause
===============================================
@echo off
echo 本檔案夾裡面的檔案有:
dir>c:\file.txt
for /f "skip=5 tokens=3* delims= " %%a in (c:\file.txt) do (
if not "%%a"=="<DIR>" if not "%%b"=="位元組" if not "%%b"=="可用位元組" echo %%b
)
del c:\file.txt
pause
===============================================
對於後面的兩個例子,其中options裡面的delims= 是可以刪除的,因為只要添加了/F開關係統就將delims的值預設為空白格。
符號字串中的最後一個字元星號,
那麼額外的變數將在最後一個符號解析之後
分配並接受行的保留文本。本例中也可以改為4,不過檔案名稱中有空格的檔案,只能顯示空格以前部分
同時我們也看到了,for語句的do後面的command也是可以分行的,只需要保證command的左括弧和do在同一行就可以了。
4、開關/D或/R
含開關/D或/R的for語句是與目錄或檔案有關的命令,一般情況下很少使用。含開關/R的命令有時候被用於通過遍曆檔案夾來尋找某一個檔案或檔案夾,故而列舉此例。
含開關/R的for語句舉例(檔案夾遍曆):
===============================================
@echo off
setlocal enabledelayedexpansion
FOR /R d: %%i IN (.) DO (
set dd=%%i
set "dd=!dd:~0,-1!"
echo !dd!
)
pause
exit
===============================================
-----------------------------------2013/5/28 13:11:04-----------------------------------
windowsbat學習總結:
批處理命令返回0為成功, 有些時候看起來命令是正確的,但是始終報錯,給命令加上括弧嘗試一下。
針對if語句,else語句始終加入括弧。
1,@, rem, ::, set, echo, pasue, goto, exit, call, choice, if, for,
2,&連續執行,不管正確錯誤, &&連續執行,直到錯誤為止, ||連續執行,直到正確為止, >建立檔案, >>追加到檔案
&, &&, ||,
true & echo good 返回0,errorlevel
false & echo good 返回1,
>, >>
echo good > file ;建立
echo good >> file ;追加
3,choice 語句結構
choice /c ync /t 5 /d y /m "please choice yes, no, cancel"
4,if語句結構
1、字串比較
set var1="1234A"
set var2="1234a"
if /I %var1% EQU %var2% (echo equal) else (echo not equal)
2、存在判斷
if exist %0 (echo exist %0) else (echo not exist %0)
3、定義判斷
set var="var"
if defined var echo (var=%var%) else echo "var not defined"
set var=
if defined var echo (var=%var%) else echo "var not defined"
4、choice判斷
errorlevel的if判斷是大於等於的,請注意,最好的是goto語句跳出去標號比較好
CHOICE /C YNC /M "確認請按 Y,否請按 N,或者取消請按 C"
choice /C dme /M "defrag,mem,end"
if errorlevel 3 echo end
if errorlevel 2 echo mem
if errorlevel 1 echo defrag
5,for語句結構
1、無開關
直接遍曆字串,以空格分隔,當遍曆的字串有空格,會出現"" 也被計入字串的情況
set list=how do "you suck" do ok
for %%i in (%list%) do echo i=%%i
直接遍曆字串,以,分隔,可以處理字串自身帶有空格的情況
set list=how,do,you suck,do,ok
for %%i in (%list%) do echo i=%%i
2、開關/L
::start為開始計數的初始值,step為每次遞增的值,end為結束值。當end小於start時,step需要設定為負數。
::固定迴圈次數的for迴圈
for /L %%i in (1, 3, 15) do echo i=%%i
3、開關/F
可以用來截取字串的某一個部分,以delims字元分隔
for /f %%a in ("1,2,10") do echo a=%%a
for /F "tokens=1-3 delims=," %%a in ("1,2,10") do echo a=%%a b=%%b c=%%c
我感覺自己可能比較常用的for迴圈:
set list=how do "you suck" do ok ;空格分隔的字串拆分
for %%i in (%list%) do echo i=%%i
set list=how,do,you suck,do,ok ;逗號分隔的字串拆分,去掉了引號的問題
for %%i in (%list%) do echo i=%%i
set list=how do you suck do ok
for %%i in (%list%) do echo i=%%i
for /L %%i in (1, 3, 15) do echo i=%%i ;控制次數的for迴圈
for /F "tokens=1-3 delims=," %%a in ("1,2,10") do echo a=%%a b=%%b c=%%c ;截取串的for語句,不應該被看作是for迴圈
cls
進階用法:
skip表明跳過前5行,tokens表明選取第三列作為%%i,後面的全部作為%%j,if判斷可以通過語句的方式實現多個條件串連判斷。
@echo off
echo 本檔案夾檔案有:
for /F "skip=5 tokens=3* delims= " %%i in ('dir') do (
::echo "i=%%i, j=%%j"
if not "%%i"=="<DIR>" if not "%%j"=="位元組" if not "%%j"=="可用位元組" (
echo %%j
)
)
-----------------------------------2013/5/28 13:46:42-------------------------------
使用方式:
bat:
set var=%str::=2% 則表示把字串abc:de中的:替換為2;
擷取字串長度
set str=teststring
:nextlost
if not "%str%"=="" (
set /a num+=1
set "str=%str:~1%"
goto nextlost
)
Test.bat: 傳入的參數為參數:c:\temp\test1.txt
認為後面的1應該指的是第一個參數
echo %~d1 =>c:
echo %~dp1 =>c:\temp\
echo %~nx1 =>test1.txt
echo %~n1 =>test1
echo %~x1 =>.txt
cho 目前的目錄路徑:%~dp0
語音:
mshta vbscript:createobject("sapi.spvoice").speak("好好學習Merry Christmas and Happy New Year!")(window.close)
for迴圈遍曆用空格間隔的字串,對每一個字串做相應的處理。
:nextfor
FOR /F "tokens=1,*" %%i in ("%serviceslist%") do (
set torestart=%%i
set serviceslist=%%j
if not "%serviceslist%"=="" (
call :restartprog
goto :nextfor
)
)
goto :end
::函數調用示範
::-----------restartprog begin---------------
:restartprog
echo "restartprog: %torestart%"
goto :EOF
::-----------restartprog end----------------
set計算求值:
set var=10
set /a var+8*2+var*2
set /a "var+8*2+var*2>>2"
延遲環境變數擴充:
setlocal enabledelayedexpansion
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "!VAR!" == "after" @echo If you see this, it worked
)
命令擴充???:還不清楚
echo %random%
echo %cd%
set v
set p
截取字串:
set var=10203040
第一數字是位置,第二個位置是長度,第二個位置如果無,預設是結尾,第一個位置如果是負數,則反方向的位置。位置從0開始
echo %var:~-4,3%
echo %var:~0%
echo %var:~1%
echo %var:~-2%
替換字串
echo %var:0=kkk% ;0替換為kkk
echo %var:10=kkk% ;10替換為kkk
echo %var:20=kkk%
echo %var:*20=kkk% ;20之前包括20字串都替換為kkk