1. 程式人生 > >Dos 命令進階——批處理(下)

Dos 命令進階——批處理(下)

Dos 命令進階(三)——批處理(下)

for命令講解思路圖

FOR命令的作用主要是用來處理文字內容

可以開啟cmd輸入"for /?" 來看下它的幫助文件

這裡羅列出for命令的四個引數 /F,/D,/R,/L . 當然這些引數也是可以不加的(引數不區分大小寫)

第一部分:

下面我們跑幾個例子, 先看沒有加任何引數的.

示例1:

@echo off

for %%a in (c:windows*.log) do echo %%a

pause

Dos 命令進階(三)——批處理(下)

for命令無引數的操作演示

首先請大家看幾個固定的格式%%a是個變數

批處理變數的命名規則是從小寫a -- 小寫z,和大寫A -- 大寫Z

例項分析:

執行命令將 (c:windows*.log) 

中的操作結果逐個賦(傳送)給 %%a 然後 Do 將 %%a 輸入給 echo指令, 就會打印出 c:windows 目錄下所有副檔名為 .log 的檔案

還有一點需要注意的:

%%a 這樣的變數命名方式只在編寫批處理指令碼時需要給變數名前加兩個%, 如果是在CMD獨立執行for命令列, 則只需要一個%, 即 %a 即可.

Dos 命令進階(三)——批處理(下)

%和%%的區別應用

好,現在我們來學習for命令的第一個引數 /d, 開啟幫助就可以看見。

系統幫助文件有說“如果資料集(set)中包含萬用字元, 則指定與目錄名匹配,而不與檔名匹配”

說明這個引數是 對目錄進行相關操作的,而不是操作檔案。

就是說, 加了 /d 這個引數的for命令列, 只能對目錄進行操作

(這樣說感覺好像容易理解一些).

/d引數的基本格式:

FOR /D %variable IN (set) DO command [command-parameters]

示例2:

@echo off

for /d %%a in (*) do echo %%a

pause

Dos 命令進階(三)——批處理(下)

for /d 引數的應用(只能操作當前目錄)

Dos 命令進階(三)——批處理(下)

for /d 引數的應用, 只操作腳本當前路徑下的目錄

Dos 命令進階(三)——批處理(下)

for /d 引數指定操作路徑

Dos 命令進階(三)——批處理(下)

for /d引數, 給指定的操作路徑兩端新增雙引號

它就只顯示批處理檔案所在當前路徑下所有的資料夾(專業點就叫目錄, directory),而檔案就不會顯示。這也就是/d這個引數的作用了,再來看個例子,也是我們前面講到過的知識

示例3:

@echo off

for /d %%a in (?indows) do echo %%a

pause

Dos 命令進階(三)——批處理(下)

for /d 在預設路徑下執行指令碼

Dos 命令進階(三)——批處理(下)

for /d 在任意路徑執行指令碼

?可以匹配任意一個字元,所以它會打印出 c: 下所有以任意字元開頭跟有indows的目錄,這一點相信難不住學過基礎的條友.

/r引數的基本格式:

FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]

檢查以 [drive:]path 為根(起始點)的目錄樹,指向每個目錄中的FOR 語句。如果在 /R 後沒有指定目錄則使用腳本當前所在目錄。如果資料集(set)為一個單點(.)字元,則列舉該目錄樹

這個r引數應該是遞迴(recursion)查尋當前目錄樹下的指定型別檔案的意思

系統幫助文件看起來不是那麼容易理解,還是直接來看例子吧, 這樣實在些:

示例1:

顯示當前目錄和子目錄下所有的副檔名為.txt的檔案

@echo off

for /r %%a in (*.txt) do echo %%a

pause

Dos 命令進階(三)——批處理(下)

預設路徑下

示例2 :

在c:的根目錄以及子目錄中搜索所有的副檔名為.exe的檔案

@echo off

for /r C:opencv %%a in (*.txt) do @echo %%a

pause

Dos 命令進階(三)——批處理(下)

指定路徑下的檔案

想要的檔案都找到了, 至於你想對找到的檔案做些啥子事情, 請在 DO 後面進行操作.

/l引數的基本格式:

FOR /L %variable IN (start,step,end) DO command [command-parameters]

該資料集表示以增量形式從開始到結束的一個數字序列。

因此,(1,1,5) 將產生序列 1 2 3 4 5,即從1開始迴圈, 每一次加1,直到5結束迴圈.

(5,-1,1) 將產生序列 (5 4 3 2 1), 即從5開始迴圈, 每一次減1, 直到1結束迴圈.

可能有的條友還不是很明白。那還來看例子

示例1:

@echo off

for /l %%a in (1,1,5) do @echo %%a

pause

Dos 命令進階(三)——批處理(下)

讓 for /l 只作計數

執行後就顯示了1 2 3 4 5,首先說下(1,1,5)對應的就是基本格式中的(start,step,end)也就是

開始數、遞增量、終止數。那麼這個do後面的命令大家可以修改啊,再來看個例子理解下

示例2:

@echo off

for /l %%a in (1,1,3) do echo 條友們萬歲!

pausefor /l

Dos 命令進階(三)——批處理(下)

也可以跑跑龍套

/f引數的基本格式:

FOR /F "ParsingKeywords" %%Variable IN (FileNameSet) DO command [command-parameters]

從幫助文件中我們知道,for命令主要是用它來解析檔案。那麼前面幾個引數並沒有關於用for來解析檔案的功能.

重頭戲就是這個/f引數了, 這個引數的功能是很強大的,大家要學好它哦

"ParsingKeywords" 代表的是下列這些選項引數:

eol=c - 指一個行註釋字元的結尾(就一個)

skip=n - 指在檔案開始時忽略的行數

delims=xxx - 指分隔符集。這個替換了空格和跳格鍵的預設分隔符集

tokens=x,y,m-n - 指每行的哪一個符號被傳遞到每個迭代的 for 本身。這會導致額外變數名稱的分配。m-n格式為一個範圍。通過 nth 符號指定 mth。如果符號字串中的最後一個字元星號,那麼額外的變數將在最後一個符號解析之後分配並接受行的保留文字。

usebackq - 指定新語法已在下類情況中使用:在作為命令執行一個後引號的字串並且一個單引號字元為文字字串命令並允許在filenameset中使用雙引號擴起檔名稱。

上面那些幫助文件的內容也只有天才才能看懂了, 反正小編沒看懂

那就一起試著來吧, 順便大家也看看熱鬧, 看看能不能理解每個引數的作用, 如果能理解, 小編的努力就算是沒白費.

示例3:

@你們好嗎

歡迎 歡迎 熱烈歡迎

感謝 條友們的 關注支援 條友們萬萬歲!

感謝 條友們的 關注支援 條友們萬萬歲!

感謝 條友們的 關注支援 條友們萬萬歲!

看清楚了嗎

;懂了吧

儲存為以個文字檔案為test.txt,用for /f來解析試試看

@echo off

for /f "[email protected] tokens=1 delims= " %%i in (test.txt) do @echo %%i

pause

Dos 命令進階(三)——批處理(下)

for /f 解析檔案內容 tokens=1

Dos 命令進階(三)——批處理(下)

for /f 解析檔案內容 tokens=4

說明:

關鍵字eol=後面的符號表示 忽略以該符號開頭的行

關鍵字tokens=1是什麼意思? 在此它表示每一行的第一塊,那麼如果tokens=2呢,當然是表示每一行的第二塊…那麼每行塊劃分的依據就是關鍵字 "delims=" 它了, 這裡是以空格來劃分的,大家可以靈活使用.

如果是別的特殊符號,比如“;”那麼就可以寫成“delims=;”, 想來大家應該有些小明白了吧

在來看示例4:

@echo off

for /f "delims=" %%i in (test.txt) do @echo %%i

pause

Dos 命令進階(三)——批處理(下)

預設解析引數的演示

這會沒加eol=這個引數

注意: for /f 預設情況下就是eol=; 所以它會顯示這些內容,

之所以加這個"delims="是因為for /f預設情況分隔符就是空格

Dos 命令進階(三)——批處理(下)

所有引數都預設

綜合理解一下上面幾個引數。

示例5:

@echo off

for /f "eol=; tokens=1,2,3 delims= " %%a in (test.txt) do @echo %%a %%b %%c

pause

Dos 命令進階(三)——批處理(下)

綜合命令引數解析例項

和上面差不多,只是多顯示了幾塊內容。注意%%a %%b %%c要按26個英文字母的順序來寫,這點希望大家記住。

再來看個例子

示例6:

@echo off

for /f "skip=5 tokens=*" %%i in (test.txt) do @echo %%i

pause

Dos 命令進階(三)——批處理(下)

for /f skip引數的使用

這個skip=5表示的是跳過前面5行數,用數字來表示,tokens=*表示顯示所有的資訊

第二部分:

另外,FOR 變數參照的替換已被增強。您現在可以使用下列選項語法:

~I - 刪除任何引號("),擴充套件 %I

%~fI - 將 %I 擴充套件到一個完全合格的路徑名

%~dI - 僅將 %I 擴充套件到一個驅動器號

%~pI - 僅將 %I 擴充套件到一個路徑

%~nI - 僅將 %I 擴充套件到一個檔名

%~xI - 僅將 %I 擴充套件到一個副檔名

%~sI - 擴充套件的路徑只含有短名

%~aI - 將 %I 擴充套件到檔案的檔案屬性

%~tI - 將 %I 擴充套件到檔案的日期/時間

%~zI - 將 %I 擴充套件到檔案的大小

%~$PATH:I - 查詢列在路徑環境變數的目錄,並將 %I 擴充套件到找到的第一個完全合格的名稱。如果環境變數名未被定義,或者沒有找到檔案,此組合鍵會擴充套件到空字串

注意: 在CMD命令提示符中執行的話需要輸入一個%號,這也是很多人容易犯的錯誤,這裡我舉幾個幾個例子來讓大家理解它們的意思:

看看這個 ~I - 刪除任何引號("),擴充套件 %I

將下列內容儲存為一個名為test.txt的文字檔案

"條友們萬萬歲!"

"條友們萬萬歲!"

"條友們萬萬歲!"

"條友們萬萬歲!"

示例1:

@echo off

for /f "delims=" %%i in (test.txt) do @echo %%~i

pause

Dos 命令進階(三)——批處理(下)

for /f 不給擴充套件變數加~時

Dos 命令進階(三)——批處理(下)

for /f 加了~的擴充套件變數的效果

Dos 命令進階(三)——批處理(下)

可用作擴充套件變數的不一定非要是 I, 其它字元也可以的

大家可以看見,其實這個引數就是用來去掉兩端引號的,但是去"號它也是有一定規律的。假如在詞語中間的"它是不會去掉。這一點希望大家注意一下

理解了這個~i,我們再來看個%~fI 的例子

示例2:

@echo off

for /f "delims==" %%i in ('dir /b') do @echo %%~fi

pause

先看一下 dir 與 dir /b 這個帶不帶 /b 引數的區別

Dos 命令進階(三)——批處理(下)

預設dir不帶任何引數

Dos 命令進階(三)——批處理(下)

dir /b 引數的作用

Dos 命令進階(三)——批處理(下)

這是在沒有使用 %~fi 這前

Dos 命令進階(三)——批處理(下)

使用 %~fi 命令擴充套件後的效果

%~fI其實就是將 %I 擴充套件到一個完全合格的路徑名(每個檔案的絕對路徑),大家可以對比一下有什麼不一樣的地方就明白了

"delims==" 這個引數的寫法, 兩個=號與一個=號的效果是一樣的, 不用糾結.

再來看下一個例子:

示例3:

@echo off

for /f "delims==" %%i in ('dir /b') do @echo %%~di

pause

Dos 命令進階(三)——批處理(下)

for /f 中 %~di變數擴充套件的效果

為什麼只顯示了批處理所在路徑的驅動器號呢,這就是%~di的關係了,它就是用來顯示批處理所在路徑驅動器號的,明白了嗎?

%~pI - 僅將 %I 擴充套件到一個路徑

示例4:

@echo off

FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~pi

pause

Dos 命令進階(三)——批處理(下)

for /f %~pi 變數擴充套件的效果

也就是只顯示路徑而不顯示檔名,那麼下面的都可從命令列幫助中就可理解了

%~sI - 擴充套件的路徑只含有短名

在來看示例5:

@echo off

for /f "delims=" %%i in ('dir/b') do @echo %%~si

pause

Dos 命令進階(三)——批處理(下)

for /f %~si 擴充套件變數的演示

從字面上也可以理解了,在系統存在有長路徑名和短路徑名,我們來看下。就比如我們要切換目錄吧,我在C:下要切換到C:Program Files目錄下我就可以輸入cd "Program Files" 注意雙引號哦, 因為目錄名中間有空格.

那麼這就是一種長路徑名的表示形式。那我們現在用短路徑名來表示它,cd PROGRA~1(字母是大寫的)是不是也切換進來了.那麼我們怎麼可以看見每個目錄的短路徑呢,可以通過輸入 dir /x 就可以看見了。

%~$PATH:I - 查詢列在路徑環境變數的目錄,並將 %I 擴充套件到找到的第一個完全合格的名稱。如果環境變數名未被定義,或者沒有找到檔案,此組合鍵會擴充套件到空字串

來看個例子就知道是什麼意思了

示例6:

FOR /F "delims==" %%i IN ("notepad.exe") DO @echo %%~$PATH:i

pause

Dos 命令進階(三)——批處理(下)

先看下圖中, 要知道PATH這個環境的值, 其值都是以分號隔開各資料夾的絕對路徑

在%PATH%路徑種搜尋指定的檔案,因為他是一個系統變數%PATH%,通過echo看下就知道它代表的是什麼意思了

Dos 命令進階(三)——批處理(下)

檢視系統環境變數的結果

最後來看下它們的組合用法

%~dpI - 僅將 %I 擴充到一個驅動器號和路徑

示例7:

@echo off

for /f "delims=" %%i in ('dir/b') do @echo %%~dpi

pause

Dos 命令進階(三)——批處理(下)

請對比 %~di, %~pi, %~dpi這三個例項來理解

前面已經說到了,只是將他們組合在一起實用而已。

%%~dI 僅將 %I 擴充套件到一個驅動器號,%~pI- 僅將 %I 擴充套件到一個路徑

%~nxI - 僅將 %I 擴充到一個檔名和副檔名.

Dos 命令進階(三)——批處理(下)

for /f 下 %~ni擴充套件變數的應用

Dos 命令進階(三)——批處理(下)

for /f 下 %~xi擴充套件變數的應用

Dos 命令進階(三)——批處理(下)

for /f 下 %~xni擴充套件變數的應用

%~fsI - 僅將 %I 擴充到一個帶有短名的完整路徑名, 跟%~si的結果相同

%~dp$PATH:i - 查詢列在路徑環境變數的目錄,並將 %I 擴充到找到的第一個驅動器號和路徑

Dos 命令進階(三)——批處理(下)

%~dp$PATH:i 擴充套件變數的用法

%~ftzaI - 將 %I 擴充到類似輸出線路的 DIR

這個也很簡單,舉例說明

最後在來看個例子

示例8:

@echo off

for /f "delims=" %%i in ("notepad.exe") do @echo %%~dp$PATH:i

pause

Dos 命令進階(三)——批處理(下)

%~$PATH:I 是用來搜尋檔案的,前面有提到。

那麼%%~dp$PATH:i是什麼意思呢。就是如果搜尋到notepad.exe這個檔案,那麼只顯示它所在的%~dI驅動器號和%~pI擴充套件到一個路徑,而檔名是不會顯示的。如果要顯示檔名那就得在加一個引數了,就是%~nI- 僅將 %I 擴充套件到一個檔名

延遲的環境變數擴充套件

要理解什麼是“延遲的環境變數擴充套件”,首先要理解什麼是“環境變數擴充套件”。

(搬磚源: https://www.cnblogs.com/minisculestep/p/4959612.html)

cmd在解釋我們的命令的時候,首先會讀取命令列一條完整的命令,然後對其進行一些命令格式的匹配操作,看你所輸的命令格式是否正確。如果我們要在命令中引用一些變數,那麼我們需要在變數的兩邊各加一個%號使cmd在解釋我們的命令的時候能夠識別這個變數,例如%name%。當cmd讀取我們的命令進行格式匹配的時候,就會發現name這個字串兩邊各加了一個%就不會把它當作普通字串處理,而是把它當作一個變數處理變數名就叫做name。然後cmd就會查詢這個變數的值用該值替換掉%name%,最後執行這個替換好的命令。這個替換的過程就叫做環境變數擴充套件

什麼是延遲的環境變數擴充套件,我們都知道命令列直譯器在解析執行批處理檔案時是將一條完整的命令來解析執行的。對於if、for這樣的命令,可以將命令巢狀在括號裡,所以一個完整的if命令可能包含多個需要執行的命令,但是cmd在解釋這類命令的時候,會把它當作一條完整的命令,從而導致出現一些問題,這個應該不難理解吧。

示例程式碼 :

@echo off

set /a var = 0

for /l %%m in (1,1,5) do (

set /a var = %%m

echo %var%

)

pause

執行結果:

Dos 命令進階(三)——批處理(下)

延遲環境變數示例

這是因為在命令執行之前,變數便進行了替換,導致巢狀在for命令裡的操作沒有體現出來。這時候,“延遲的環境變數擴充套件”的概念被提出來了“延遲的環境變數擴充套件”,即每條命令在執行之前,才將變數進行替換,以保證對變數的任何修改都可以實時生效。

我們可以使用“setlocal enabledelayedexpansion”命令來開啟延遲的環境變數擴充套件,啟用後,我們使用 !name! 來進行取值,而不是%name%

修改後的程式碼如下:

@echo off

setlocal enabledelayedexpansion

set /a var = 0

for /l %%m in (1,1,5) do (

set /a var = %%m

echo !var!

)

pause

執行結果:

Dos 命令進階(三)——批處理(下)

開啟延遲變數擴充套件功能後