題外話:又到了周三晚上,2019年下半年的學習目標一也已經告一段落,就把最近學習總結的批處理發(fā)出來了,一則是方便以后自己翻閱,二則也可以分享給那些想學習批處理的朋友。
什么是批處理
????????批處理定義:顧名思義,批處理文件是將一系列命令按一定的順序集合為一個可執(zhí)行的文本文件,其擴展名為BAT或者CMD。這些命令統(tǒng)稱批處理命令。
接下來我將分成?常用基礎命令?和?常用進階命令?兩部分進行講解:
? ??????????????????????一、常用基礎命令
1、echo 和 @
1、echo是回顯的意思,就是你的代碼命令是否要顯示在控制臺上面,如果關閉回顯,那么只會顯示運行結果,不會顯示運行的代碼
? ??????語法:echo [{ on|off }]
??? 2、@字符放在命令前將關閉該命令回顯,無論此時echo是否為打開狀態(tài)。常用寫法:@echo off即關閉本條回顯,以及后面的所有回顯
??? 3、echo 作為輸出提示信息關鍵字,類似print,debug.log等等。
????? ??語法:echo?信息內容
????????比如:echo hello bat
??? 4、關閉DOS命令提示符
?????????在DOS提示符狀態(tài)下鍵入echo off,能夠關閉DOS提示符的顯示使屏幕只留下光標,直至鍵入echo ON,提示符才會重新出現(xiàn)。
5、輸出空行,即相當于輸入一個回車
????????語法:echo.(echo后面沒有空格,直接跟著點.)
2、REM?和 ::
??? 這兩個關鍵字都是起到注釋本行命令的作用。REM為注釋命令,一般用來給程序加上注解,該命令后的內容不被執(zhí)行,但能回顯(可以被@echo off關閉)。與rem?不同的是, ::后的字符行在執(zhí)行時不會回顯,?無論是否用echo on是否打開(可以用于標注代碼)
??? Tips:上面兩個關鍵字都只能實現(xiàn)單行注釋,想實現(xiàn)多行注釋,可以使用goto語句小技巧來實現(xiàn):
????goto start
????::正中間的內容是注釋內容,原理就是goto語句跳過了這里面的命名執(zhí)行下面了
????:start
3、PAUSE
????用來暫停指令的執(zhí)行,同時又不立刻關閉窗口,這樣你就可以看到你指令執(zhí)行的結果了。
????Tips:1、可以在鍵盤上按下Ctrl+C組合鍵來強行終止一個批處理的執(zhí)行過程。
2、要顯示其他提示語,可以這樣用:echo?其他提示語& pause > nul

4、set
語法形式:
SET [variable=[string]]
SET /Pvariable=[promptString]
SET /A expression
(1)定義變量
set var=10?::=號兩邊不能有空格
set var=::給變量賦值是定義變量,不給變量賦值類似于注銷變量
(2)SET /A expression
/A 讓SET可以支持數學符號進行加減等一些數學運算,該表達式解析很簡單并以遞減的優(yōu)先順序支持下列操作:
() - 分組??
! ~ - - 一元運算符??
* / % - 算數運算符??
+ - - 算數運算符??
<< >> - 邏輯移位??
& - 按位“與”??
^ - 按位“異”??
| - 按位“或”??
= *= /= %= += -= &= ^= |=
<<= >>= - 賦值?
, - 表達式分隔符
測試指令如下:
@echo off Setlocalenabledelayedexpansion
set a=100
set b=1000
set /a c=a+b
echo the result is :%c%
set /a a=1+1,b=2+1,c=3+1
echo %a% %b% %c%
? set /a var= 1
"&" 1?::邏輯或區(qū)域操作等運算符,需要用雙引號引起來
set /a var= 1 "%" 1
set /a var= 2"<<" 2
set /a var= 4">>" 2
pause
(3)SET /P variable=[promptString]
功能等待用戶輸入
windows 2000 和windows 是沒有choice這個命令,choice的等待用戶輸入功能就要通過set /p來實現(xiàn)
測試指令如下:
@echo off
Setlocal enabledelayedexpansion
set /p str=請輸入你想輸入的字符:
echo 你輸入的字符串為:%str%
pause
(4)結合字符串操作,對變量的內容進行剪切、替換等操作
@echo off
Setlocal enabledelayedexpansion
set str=welcome come to bat
set var=%str:~3,4%
echo %var%
pause
(5)顯示環(huán)境變量
如:
set 會顯示當前所有的系統(tǒng)環(huán)境變量
set c 會顯示當前所有的以c開頭或C開頭的變量(不區(qū)分大小寫)
5、ERRORLEVEL
程序返回碼
echo %errorlevel%
每個命令運行結束,可以用這個命令行格式查看返回碼,用于判斷剛才的命令是否執(zhí)行成功.
默認值為0,命令執(zhí)行成功則返回0,執(zhí)行出錯會設?errorlevel?為1
6、title
設置cmd窗口的標題
title?新標題 ???????#可以看到cmd窗口的標題欄變了
7、COLOR
設置默認的控制臺前景和背景顏色。
COLOR [attr]? attr 指定控制臺輸出的顏色屬性
顏色屬性由兩個十六進制數字指定?--?第一個為背景,第二個則為前景。每個數字可以為以下任何值之一:
????0 =?黑色 ??????8 =?灰色
????1 =?藍色 ??????9 =?淡藍色
????2 =?綠色 ??????A =?淡綠色 //不區(qū)分大小寫
????3 =?湖藍色 ????B =?淡淺綠色
????4 =?紅色 ??????C =?淡紅色
????5 =?紫色??????D =?淡紫色
????6 =?黃色 ??????E =?淡黃色
????7 =?白色 ??????F =?亮白色
例如:COLOR FC
如果沒有給定任何參數,該命令會將顏色還原到?CMD.EXE?啟動時的顏色。這個值來自當前控制臺窗口、/T?開關或DefaultColor?注冊表值。如果用相同的前景和背景顏色來執(zhí)行?COLOR?命令,COLOR?命令會將?ERRORLEVEL?設置為?1。
8、goto 和?:
在批處理中允許以“:XXX”來構建一個標號,然后用goto XXX跳轉到標號:XXX處,然后執(zhí)行標號后的命令。
例:
if {%1}=={} goto noparms
if "%2"=="" goto noparms
標簽的名字可以隨便起,但是最好是有意義的字符串啦,前加個冒號用來表示這個字符串是標簽,goto命令就是根據這個冒號(:)來尋找下一步跳到到那里。
@echo off
Setlocal enabledelayedexpansion
:start
set /p var=請輸入一個大于3的數字
echo %var%
if %var% leq 3 goto start
pause
9、find
在文件中搜索字符串。
FIND [/V] [/C] [/N] [/I] [/off[LINE]] "string"
[[drive:][path]filename[ ...]]
??/V ???????顯示所有未包含指定字符串的行。
??/C ???????僅顯示包含字符串的行數。
??/N ???????顯示行號。
??/I ? ? ? ??搜索字符串時忽略大小寫。
??/off[LINE] 不要跳過具有脫機屬性集的文件。
??"string" ? ? 指定要搜索的文字串,
??[drive:][path]filename 指定要搜索的文件。
如果沒有指定路徑,F(xiàn)IND?將搜索鍵入的或者由另一命令產生的文字。
Find常和type命令結合使用
Type [drive:][path]filename | find "string" [>tmpfile] #挑選包含string的行
Type [drive:][path]filename | find /v "string" ??#剔除文件中包含string的行
Type [drive:][path]filename | find /c ??#顯示文件行數?
10、start?命令
Start會開啟新窗口來運行程序,如果新窗口不正常退出,你的批處理就不能正常執(zhí)行下去?
語法:start ["title"] [/dPath]
[/i] [/min] [/max] [{/separate | /shared}] [{/low | /normal | /high | /realtime
| /abovenormal | belownormal}] [/wait] [/b] [FileName] [parameters]?
"title" 指定在“命令提示符”窗口標題欄中顯示的標題。?
/dpatch 指定啟動目錄。?
/i 將 Cmd.exe 啟動環(huán)境傳送到新的“命令提示符”窗口。?
/min 啟動新的最小化窗口。?
/max 啟動新的最大化窗口。?
/separate 在單獨的內存空間啟動 16 位程序。?
/shared 在共享的內存空間啟動 16 位程序。?
/low 以空閑優(yōu)先級啟動應用程序。?
/normal 以一般優(yōu)先級啟動應用程序。?
/high 以高優(yōu)先級啟動應用程序。?
/realtime 以實時優(yōu)先級啟動應用程序。?
/abovenormal 以超出常規(guī)優(yōu)先級的方式啟動應用程序。?
/belownormal 以低出常規(guī)優(yōu)先級的方式啟動應用程序。?
/wait 啟動應用程序,并等待其結束。
? ??????????????????????二、常用進階命令
1、字符串的操作
????????常用的字符操作有截取通過“:~來進行處理”,如果想把截取或者替換后的字符串賦值給另一個變量,直接使用set即可。(如果中文出現(xiàn)亂碼,把文件編碼改成ANSI)。常用的字符串操作有:1、截取字符串?2、替換字符串?3、字符串合并?4、擴充字符串。效果如下圖:

2、if語句的使用
????在cmd使用?if /??打開if的系統(tǒng)幫助,可以看到基本語法有下面三種,需要注意的是if和else盡量保持在同一行上面。

測試代碼如下:

3、for語句的使用
for語句的幾種用法如下:
a、for語句的基本用法
b、for /f (delims、tokens、skip、eol、userbackq、變量延遲)
c、for /r (遞歸遍歷)
d、for /d (遍歷目錄)
e、for /l (計數循環(huán))
1、for語句的基本用法

for語句的基本要素:
? 1、for、in和do是for語句的關鍵字,它們三個缺一不可;
? 2、%%I是for語句中對形式變量的引用,就算它在do后的語句中沒有參與語句的執(zhí)行,也是必須出現(xiàn)的;
? 3、in之后,do之前的括號不能省略;
? 4、command1表示字符串或變量,command2表示字符串、變量或命令語句;

For語句的執(zhí)行過程
?? 1、for語句的形式變量I,可以換成26個字母中的任意一個,這些字母會區(qū)分大小寫,也就是說,%%I和%%i會被認為不是同一個變量;形式變量I還可以換成其他的字符,但是,為了不與批處理中的%0~%9這10個形式變量發(fā)生沖突,請不要隨意把%%I替換為%%0 ~%%9中的任意一個;
?? 2、in和do之間的command1表示的字符串或變量可以是一個,也可以是多個,每一個字符串或變量,我們稱之為一個元素,每個元素之間,用空格鍵、跳格鍵、逗號、分號或等號分隔;
?? 3、for語句依次提取command1中的每一個元素,把它的值賦予形式變量I,帶到do后的command2中參與命令的執(zhí)行;并且每次只提取一個元 素,然后執(zhí)行一次do后的命令語句,而無論這個元素是否被帶到command2中參與了command2的運行;當執(zhí)行完一次do后的語句之后,再提取 command1中的下一個元素,再執(zhí)行一次command2,如此循環(huán),直到command1中的所有元素都已經被提取完畢,該for語句才宣告執(zhí)行結 束;
其中,第3點是最為關鍵的,它描述了for語句的執(zhí)行過程,是for語句的精髓所在,大家一定要牢記這一條,才能深刻理解更為復雜的for流程。
2、文本解析顯神威:for /f 用法詳解
1、/f逐行讀完文件內的文本內容

2、切分字符串的利器:delims=
test.txt內的中文文本,被,分隔看了。注意,有中文文本,保存為ANSI格式

3、定點提?。簍okens=
tokens= 后面一般跟的是數字,如 tokens=2,也可以跟多個,但是每個數字之間用逗號分隔,如 tokens=3,5,8,它們的含義分別是:提取第2節(jié)字符串、提取第3、第5和第8節(jié)字符串。注意,這里所說的“節(jié)”,是由 delims= 這一開關劃分的,它的內容并不是一成不變的。

4、跳過無關內容,直奔主題:skip=n
for /f 允許你跳過這些無用的行,直接從第N+1行開始處理,這個時候,就需要使用參數 skip=n,其中,n是一個正整數,表示要跳過的行數。

這段代碼將跳過頭兩行內容,從第3行起顯示test.txt中的信息。
5、忽略以指定字符打頭的行:eol=
eol= 的準確含義是:忽略以指定字符打頭的行

3、遍歷文件夾:for /r
1、for /r 的作用及用法
按照幫助信息里文縐縐的說法,for /r 的作用是“遞歸”,我們換一個通俗一點的,叫“遍歷文件夾”,它會遍歷指定目錄和子目錄下的所有文件和文件夾。
更詳細的解釋就是:在下面的語句中,如果“元素集合”中只是一個點號,那么,這條語句的作用就是:列舉“目錄”及其之下的所有子目錄,對這些文件夾都 執(zhí)行“命令語句集合”中的命令語句。其作用與嵌套進 for /f 復合語句的 "dir /ad /b /s 路徑" 功能類似。如果省略了“目錄”,將在當前目錄下執(zhí)行前面描述的操作。
for /r 目錄 %%i in (元素集合) do 命令語句集合

?@echo off
for /r d:\test %%i in (.) doecho %%i
pause
執(zhí)行的結果如下所示:
d:\test\.
d:\test\1\.
d:\test\2\.
d:\test\3\.
效果就是顯示 d:\test 目錄及其之下是所有子目錄的路徑,其效果與 dir /ad /b
/s d:\test 類似。若要說到兩者的區(qū)別,可以歸納出3點:
1、for /r 列舉出來的路徑最后都帶有斜杠和點號,而 dir 語句則沒有,會對獲取到的路徑進行進一步加工產生影響;
2、for /r 不能列舉帶隱藏屬性的目錄,而 dir 語句則可以通過指定 /a 后面緊跟的參數來獲取帶指定屬性的目錄,更加靈活;
3、若要對獲取到的路徑進行進一步處理,則需要把 dir 語句放入 for /f 語句中進行分析,寫成?for /f %%i in ('dir /ad /b /s')
do …… 的形式;由于 for /r 語句是邊列舉路徑邊進行處理,所以,在處理大量路徑的時候,前期不會感到有停頓,而 for /f 語句則需要等到 dir /ad /b
/s 語句把所有路徑都列舉完之后,再讀入內存進行處理,所以,在處理大量路徑的時候,前期會感到有明顯的停頓。
第2點差別很容易被大家忽視,導致用 for /r 列舉路徑的時候會造成遺漏;而第3點則會讓大家有更直觀的感受,很容易感覺到兩者之間的差別。
要是“元素集合”不是點號呢?那又如何?
@echo off
for /r d:\test %%i in (a b c) doecho %%i
pause
運行的結果是:
D:\test\1\a
D:\test\1\b
D:\test\1\c
D:\test\2\a
D:\test\2\b
D:\test\2\c
D:\test\3\a
D:\test\3\b
D:\test\3\c
原來,它的含義是:列舉 d:\test 及其所有的子目錄,對所有的目錄路徑都分別添加a、b、c之后再顯示出來。
@echo off
for /r d:\test %%i in (*.txt) doecho %%i
pause
運行結果是:
D:\test\test.txt
D:\test\1\1.txt
D:\test\1\2.txt
D:\test\2\a.txt
D:\test\2\b.txt
D:\test\3\1.txt
這段代碼的含義是:列舉 d:\test 及其所有子目錄下的txt文本文件(以.txt結尾的文件夾不會被列出來)。
我們再回過頭來歸納一下這個語句的作用:
for /r 目錄 %%i in (元素集合) do 命令語句集合
上面語句的作用是:
? 1、列舉“目錄”及該目錄路徑下所有子目錄,并把列舉出來的目錄路徑和元素集合中的每一個元素拼接成形如“目錄路徑\元素”格式的新字符串,然后,對每一條這樣的新字符串執(zhí)行“命令語句集合”中的每一條命令;
特別的是:當“元素集合”帶以點號分隔的通配符?或*的時候,把“元素集合”視為文件(不視為文件夾),整條語句的作用是匹配“目錄”所指文件夾及其所有子文件夾下匹配的文件;若不以點號分隔,則把“元素集合”視為文件夾(不視為文件);
2、當省略掉“目錄”時,則針對當前目錄;
3、當元素集合中僅僅是一個點號的時候,將只列舉目錄路徑;
4、計數循環(huán):for /l
/l 者,/loop的縮寫是也,從鳥語翻譯過來,loop就是循環(huán)的意思。實際上,所有的for語句,都可以看成是一種“循環(huán)”,只是在/l中,特指按照指定次數進行循環(huán)罷了。
for /l 語句的完整格式是這樣的:
for /l %%i in (x,y,z) do (……)
在這個語句中,x、y和z都只能取整數,正負皆可,x指代起始值,y指代步長,z為終止值,具體含義為:從x開始計數,以y為步長,直至最接近 z的那個整數值為止,這之間有多少個數,do后的語句就執(zhí)行多少次。

在以上的代碼中,初始值是1,步長為2,終止值為10,表明計數從1開始,每隔2個數計算一次,直至最接近10的那個整數,羅列出來,就是1,3,5,7,9,再下一個就是11,超過10了,不再計算在內,所以,do后的語句只執(zhí)行5次,將連續(xù)顯示5個bathome。
實際上,x,y和z的值可正可負,甚至為0,限制非常寬松:
?1、步長y的值不能為0;
?2、當步長y的值為正整數時,終止值z不能小于初始值x;
?3、當步長y的值為負整數的時候,終止值z不能大于初始值x。
換而言之,必須保證in和do之間能取到一個有效的數組序列。