Windows 批處理指令碼
本書描述並展示瞭如何使用 Microsoft 提供的命令直譯器 cmd.exe 及其關聯命令,以及如何為直譯器編寫 Windows 批處理指令碼。cmd.exe 是所有基於 Windows NT 的作業系統上的預設直譯器,包括 Windows XP、Windows 7 和 Windows 10。
本書討論適用於基於 Windows NT 環境的現代 Windows 版本的 32 位 Windows 命令。它不討論特定於 DOS 環境和基於 DOS 的作業系統(如 Windows 95、Windows 98 和 Windows Me)的命令,其 Microsoft 提供的命令直譯器實際上是 DOS 程式,而不是 Win32 程式。
您可以使用 VER 命令找出您正在執行的 Windows 版本。
本書首先描述如何使用 Windows NT 命令直譯器,它如何接收、解析和處理使用者的命令。然後描述可用的各種命令。
要獲取 Windows 命令及其簡要摘要的完整列表,請在任何 Windows 計算機上開啟命令提示符,然後鍵入help。要了解特定命令的資訊,請鍵入命令名稱後跟“/?”。
本書的主題也稱為“批處理程式設計”,即使“批處理”不僅指 MS DOS 和 Windows 命令直譯器的批處理檔案。其他主題術語包括“批處理檔案程式設計”、“批處理檔案指令碼”、“Windows 批處理命令”、“Windows 批處理檔案”、“Windows 命令列”、“Windows 命令提示符”和“Windows shell 指令碼”。
對於 Windows 指令碼,cmd.exe 是一種傳統技術;現代等效項是 PowerShell,它基於 .NET,其管道流是物件,而不是字元(位元組)流。PowerShell 的功能遠遠超過 cmd.exe;PowerShell 具有完整程式語言的功能,包括變數的型別化內容、浮點運算、大整數、透過 .NET 類進行 GUI 程式設計等。儘管如此,cmd.exe 對於簡單的指令碼和命令列互動任務仍然有用,通常提供更短的語法和更快的啟動時間,以及使用其他作業系統熟悉的字元流管道。cmd.exe 可以透過其他作業系統中已知的命令進行增強;請參閱 #Unix 命令。另一種用於 Windows 指令碼的替代方案是流行的 Python 及其 pywin32 和 wmi 庫;但是,這需要安裝。
將命令列解析為一系列命令的過程很複雜。主要有四個組成部分
- 變數替換:掃描命令列以查詢變數規範,並用這些變數的內容替換找到的任何變數。
- 引用:可以引用特殊字元,以刪除其特殊含義。
- 語法:根據語法將命令列開發成一系列命令。
- 重定向:在執行序列中的單個命令之前,應用重定向規範並將其從命令列中刪除。
命令列可以包含變數規範。這些規範由一個 % 字元、一個名稱以及一個第二個 % 字元組成,除非名稱是 0 到 9 之間的數字或星號 *。
變數規範按如下方式替換為值
- %varname%,例如 %PATH% 或 %USERNAME% ,將替換為命名環境變數的值。例如,%PATH% 將替換為 PATH 環境變數的值。變數名稱匹配不區分大小寫:%PATH% 和 %path% 效果相同。
- %n,其中 0 <= n <= 9,例如 %0 或 %9,將替換為呼叫批處理檔案時傳遞給它的第 n 個引數的值,受 SHIFT 命令隨後進行的任何修改的影響。例如:%2 將替換為第二個批處理檔案引數的值。在互動式使用(批處理檔案之外)中,此情況不會進行替換。
- %* 將替換為所有命令列引數的值,除了 %0 之外,即使是索引 9 之後的引數。 SHIFT 命令對 %* 的結果沒有影響。另請參閱 命令列引數。在互動式使用(批處理檔案之外)中,此情況不會進行替換。
某些變數名稱無法使用 SET 命令檢視。相反,它們可以透過 % 符號進行讀取。要了解這些變數,請鍵入“help set”。
特殊變數名稱及其擴充套件內容
| 名稱 | 使用的替換值 |
|---|---|
| %CD% | 當前目錄,如果它不是當前驅動器的根目錄,則不以斜槓字元結尾。另請參閱 #CD。 |
| %TIME% | 系統時間,格式為 HH:MM:SS.mm,除非區域設定另有規定。另請參閱 #TIME。 |
| %DATE% | 系統日期,格式特定於本地化。另請參閱 #DATE。 |
| %RANDOM% | 生成的偽隨機數,介於 0 和 32767 之間。另請參閱 #計算。 |
| %ERRORLEVEL% | 最後一個執行的命令或最後一個呼叫的批處理指令碼返回的錯誤級別。另請參閱 #錯誤級別。 |
| %CMDEXTVERSION% | cmd.exe 當前使用的命令處理器擴充套件的版本號。 |
| %CMDCMDLINE% | 啟動當前 cmd.exe 時使用的命令列的內容。 |
連結
您可以防止控制命令語法的特殊字元具有其特殊含義,方法如下,但百分號 (%) 除外
- 您可以用引號括住包含特殊字元的字串。
- 您可以在特殊字元之前立即放置脫字元 (^)(跳脫字元)。在管道 (|) 後面的命令中,您需要使用三個脫字元 (^^^) 才能使其工作。
需要引用或轉義的特殊字元通常是 <、>、|、& 和 ^。在某些情況下,! 和 \ 可能需要轉義。換行符也可以使用脫字元轉義。
當您使用引號括住字串時,它們會成為傳遞給呼叫的命令的引數的一部分。相反,當您使用脫字元作為跳脫字元時,脫字元不會成為傳遞的引數的一部分。
百分號 (%) 是一種特殊情況。在命令列中,它不需要引用或轉義,除非使用兩個百分號來指示變數,例如 %OS%。但在批處理檔案中,您必須使用雙百分號 (%%) 以生成單個百分號 (%)。將百分號括在引號中或在其前面加上脫字元不起作用。
示例
- echo "Johnson & son"
- 回顯整個字串,而不是在 & 字元處拆分命令列。引號也會回顯
- echo Johnson ^& son
- 如上所示,但在特殊字元 & 之前使用脫字元。沒有回顯引號。
- echo Johnson & son
- 不使用跳脫字元,因此,“son”被解釋為單獨的命令,通常會導致找不到命令 son 的錯誤訊息。
- echo A ^^ B
- 回顯 A ^ B。脫字元也需要轉義,否則它會被解釋為轉義空格。
- echo > NUL | echo A ^^^^ B
- 回顯 A ^ B。在管道之後,用於轉義的脫字元需要加倍才能生效;第四個脫字元是正在轉義的脫字元。
- if 1 equ 1 ^
echo Equal &^
echo Indeed, equal- 回顯這兩個字串。行尾的脫字元轉義了換行符,導致三行被視為一行。第一個脫字元之前的空格是必要的,否則 1 會與後面的 echo 連線起來,產生 1echo。
- attrib File^ 1.txt
- 不顯示名為“File 1.txt”的檔案的屬性,因為空格的轉義不起作用。使用引號,如 attrib "File 1.txt",可以正常工作。
- echo The ratio was 47%.
- 如果從批處理檔案中執行,則忽略百分號。
- echo The ratio was 47%%.
- 如果從批處理檔案中執行,則百分號輸出一次。
- set /a modulo=14%%3
- 如果從批處理檔案中執行,則將 modulo 變數設定為 2,即 14 除以 3 的餘數。單個 % 不起作用。
- for %%i in (1,2,3) do echo %%i
- 如果從批處理檔案中執行,則輸出 1、2 和 3。
- echo %temp%
- 即使從批處理檔案中執行,也會輸出 temp 變數的內容。在批處理檔案中使用百分號訪問環境變數和傳遞的引數不需要轉義。
- echo ^%temp^%
- 從命令列執行時,輸出 %temp% 本身。
- echo %%temp%%
- 從批處理檔案中執行時,輸出 %temp% 本身。
- echo //comment line | findstr \//
- 命令 FINDSTR 使用反斜槓 (\) 進行轉義。與脫字元不同,這是命令內部的,命令外殼不知道。
連結
命令列根據語法展開為一系列命令。在該語法中,簡單命令可以組合成管道,而管道又可以組合成複合命令,最後可以轉換為帶括號的命令。
簡單命令只是一個命令名稱、一個命令尾部和一些重定向規範。簡單命令的一個示例是dir *.txt > somefile.
管道是由“管道”元字元“|”(也稱為“豎線”)連線在一起的幾個簡單命令。每個豎線之前的簡單命令的標準輸出透過管道連線到其後的簡單命令的標準輸入。命令直譯器並行執行管道中的所有簡單命令。管道(包含兩個簡單命令)的一個示例是dir *.txt | more.
複合命令是一組由連線詞分隔的管道。管道按順序執行,一個接一個,連線詞控制命令直譯器是否執行下一個管道。複合命令(包含兩個管道,管道本身只是簡單命令)的一個示例是move file.txt file.bak && dir > file.txt.
連線詞
- & - 無條件連線詞。當前管道執行完成後,始終執行下一個管道。
- && - 正條件連線詞。如果當前管道以零退出狀態完成執行,則執行下一個管道。
- || - 負條件連線詞。如果當前管道以非零退出狀態完成執行,則執行下一個管道。
帶括號的命令是用括號括起來的複合命令(即(和))。從語法的角度來看,這將複合命令轉換為簡單命令,其整體輸出可以重定向。
例如:命令列( pushd temp & dir & popd ) > somefile導致整個複合命令的標準輸出( pushd temp & dir & popd )重定向到somefile。
連結
在執行序列中的單個命令之前應用重定向規範,並將其從命令列中刪除。重定向規範控制簡單命令的標準輸入、標準輸出和標準錯誤檔案控制代碼指向的位置。它們會覆蓋可能由管道導致的對這些檔案控制代碼的任何影響。(請參閱前面關於命令語法的部分。)重定向符號 > 和 >> 可以以 1(表示標準輸出,與無字首相同)或 2(表示標準錯誤)為字首。
重定向規範為
- < filename
- 將標準輸入重定向到從命名檔案讀取。
- > filename
- 將標準輸出重定向到指定的命名檔案,覆蓋其先前的內容。
- > filename
- 將標準輸出重定向到指定的命名檔案,追加到其先前內容的末尾。
- >>h
- 重定向到控制代碼h,其中控制代碼可以是 0 - 標準輸入,1 - 標準輸出,2 - 標準錯誤,以及更多。
- <&h
- 從控制代碼h重定向。
示例
- dir *.txt >listing.log
- 將dir命令的輸出重定向到listing.log檔案。
- dir *.txt > listing.log
- 如上所述;檔名之前的空格沒有區別。但是,如果在命令視窗中輸入此命令,在輸入“> l”後使用Tab鍵進行自動完成實際上有效,而使用“>listing.log”則無效。
- dir *.txt 2>NUL
- 將dir命令的錯誤重定向到無處。
- dir *.txt >>listing.log
- 將dir命令的輸出重定向到listing.log檔案,並追加到檔案末尾。因此,在執行重定向命令之前檔案的內容不會丟失。
- dir *.txt >listing.log 2>&1
- 將dir命令的輸出以及錯誤訊息重定向到listing.log檔案。
- dir *.txt >listing.log 2>listing-errors.log
- 將dir命令的輸出重定向到listing.log檔案,並將錯誤訊息重定向到listing-errors.log檔案。
- >myfile.txt echo Hello
- 重定向可以在命令之前。
- echo Hello & echo World >myfile.txt
- 只有第二個echo被重定向。
- (echo Hello & echo World) >myfile.txt
- 兩個echo的輸出都被重定向。
- type con >myfile.txt
- 將控制檯輸入(con)重定向到檔案。因此,允許使用者輸入多行,並透過使用者按下Ctrl + Z來終止。另請參見#使用者輸入。
- (for %i in (1,2,3) do @echo %i) > myfile.txt
- 將迴圈的整個輸出重定向到檔案。
- for %i in (1,2,3) do @echo %i > myfile.txt
- 每次進入迴圈體時都重新開始重定向,丟失了除最新迴圈迭代之外的所有輸出。
連結
(...)
命令直譯器在每次執行一行或括號分組後重新載入批處理的內容。
如果啟動以下批處理並在啟動後不久將批處理中的“echo A”更改為“echo B”,則輸出將為B。
@echo off ping -n 6 127.0.0.1 >nul & REM wait echo A
單行上的內容很重要;在執行後更改以下批處理中的“echo A”不會有任何影響
@echo off ping -n 6 127.0.0.1 >nul & echo A
啟動後更改對用(和)括起來的命令也沒有任何影響。因此,在啟動以下批處理後更改“echo A”不會有任何影響
@echo off for /L %%i in (1,1,10) do ( ping -n 2 127.0.0.1 >nul & REM wait echo A )
其他任何包含,包括此包含,也是如此
@echo off ( ping -n 6 127.0.0.1 >nul & REM wait echo A )
命令直譯器程序的環境變數會被其執行的任何(外部)命令的程序繼承。一些環境變數由命令直譯器本身使用。更改它們會改變其操作。
要取消設定變數,請將其設定為空字串,例如“set myvar=”。
命令直譯器從建立它的程序繼承其初始的環境變數集。例如,對於從桌面快捷方式呼叫的命令直譯器,這將是Windows資源管理器。
命令直譯器通常具有文字使用者介面,而不是圖形使用者介面,因此無法識別通知應用程式登錄檔中環境變數模板已更改的Windows訊息。更改控制面板中的環境變數將導致Windows資源管理器從登錄檔中的模板更新其自己的環境變數,從而更改任何隨後呼叫的命令直譯器將繼承的環境變數。但是,它不會導致正在執行的命令直譯器從登錄檔中的模板更新其環境變數。
另請參見#變數替換。
連結
COMSPEC環境變數包含命令直譯器程式檔案的完整路徑名。這只是從父程序繼承的,因此間接地派生自注冊表中環境變數模板中COMSPEC的設定。
PATH環境變數的值包含一個目錄名稱列表,這些名稱由分號字元分隔。這是按順序搜尋的目錄列表,用於查詢要執行的外部命令的程式檔案。
PATHEXT環境變數的值是檔名副檔名的列表,由分號(“;”)分隔。這是按順序應用的檔名副檔名列表,用於查詢要執行的外部命令的程式檔案。
"echo %PATHEXT%"列印的PATHEXT示例內容
- .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
透過將“.PL”新增到變數中,可以確保即使在不帶“.pl”副檔名的情況下鍵入,Perl程式也能從命令列執行。因此,無需鍵入“mydiff.pl a.txt b.txt”,只需鍵入“mydiff a.txt b.txt”即可。
在Windows Vista及更高版本中將“.PL”新增到變數
- setx PATHEXT %PATHEXT%;.PL
- 如果使用Windows XP中提供的“set”,則效果是臨時的,並且隻影響當前控制檯或程序。
連結
PROMPT環境變數控制命令直譯器顯示提示時發出的文字。命令直譯器在互動模式下提示輸入新命令列時或在批處理檔案模式下回顯批處理檔案行時顯示提示。
PROMPT環境變數值中的各種特殊字元序列在顯示提示時會導致各種特殊效果,如下表所示
| 字元 | 擴充套件結果 |
|---|---|
| $$ | $字元本身 |
| $A | &符號,也稱為與號。一個便利,因為它很難在使用SET命令時將字面量&放在PROMPT環境變數的值中。 |
| $B | 豎線'|'(管道符號) |
| $C | 左括號'(' |
| $D | 當前日期 |
| $E | ESC(ASCII碼27) |
| $F | 右括號')' |
| $G | 大於號'>' |
| $H | 退格鍵(刪除前一個字元) |
| $L | 小於號'<' |
| $M | 如果當前驅動器是網路驅動器,則連結到當前驅動器的遠端名稱;否則為空字串。 |
| $N | 當前驅動器磁碟機代號 |
| $P | 當前驅動器磁碟機代號和完整路徑 |
| $Q | '='(等號) |
| $S | ' '(空格字元) |
| $T | 當前系統時間 |
| $V | Windows版本號 |
| $_ | <CR>(回車符,也稱為“enter”) |
| $+ | 與pushd目錄堆疊中的專案數量一樣多的加號(+) |
連結
大多數Windows命令都提供開關,也稱為選項,以指導其行為。
觀察結果
- 開關通常由單個字母組成;一些開關由多個字母的序列組成。
- 開關前面是斜槓(/),而不是像某些其他作業系統那樣使用減號(-)。
- 開關不區分大小寫,而不是像某些其他作業系統那樣區分大小寫。
- 如果將來自其他作業系統的命令移植到Windows(例如grep),它通常會保留原始作業系統的選項約定,包括使用減號和區分大小寫。
示例
- dir /?
- 輸出幫助。許多命令都提供此選項。
- dir /b /s
- 遞迴列出當前資料夾中的所有檔案和資料夾。使用兩個開關:b和s。
- dir /bs
- 無效;開關不能累積在一個斜槓後面。
- findstr /ric:"id: *[0-9]*" File.txt
- 與許多其他命令不同,findstr允許在一個斜槓後面累積開關。實際上,r、i和c是單個字母開關。
- dir/b/s
- 有效。在dir中,命令與第一個開關之間或開關之間的空格不影響結果;因此,與dir /b /s相同。
- tree/f/a
- 無效,與tree /f /a不同。在tree中,空格分隔是必須的。find/i/v也不起作用。
- dir /od
- 開關字母o由一個字母進一步修改,指定按日期排序。字母d本身不是開關。類似的情況包括dir /ad和more /t4。
- dir /B /S
- 開關不區分大小寫,與某些其他作業系統不同。
- sort /r file.txt
- 以相反的順序對檔案進行排序。
- sort /reverse file.txt
- Sort允許開關字串的長度超過單個字母。
- sort /reve file.txt
- Sort允許指定的開關字串是開關完整長名稱的子字串。因此,與上面相同。
- sort /reva file.txt
- 無效,因為“reva”不是“reverse”的子字串。
- taskkill /im AcroRd32.exe
- Taskkill 命令需要使用多字母開關名稱,例如 /im;縮寫為 /i 不起作用。
- java -version
- Java 誕生於另一個作業系統系列的環境中,其開關(也稱為選項)使用減號約定。
- grep --help
- 如果安裝了 GNU grep,則需要在多字母開關前加上兩個連字元。
命令通常在執行結束時設定錯誤級別。在 Windows NT 及更高版本中,它是一個 32 位有符號整數;在 MS DOS 中,它曾經是一個 0 到 255 的整數。關鍵詞:返回碼、退出碼、退出狀態。
錯誤級別的常規含義
- 0 - 成功
- 非 0 - 失敗
- 設定的錯誤級別通常為正數。
- 如果命令不區分各種型別的失敗,則失敗時的錯誤級別通常為 1。
錯誤級別的用途
示例
- dir >NUL && echo Success
- 只有當錯誤級別為零時,才會執行 && 後面的部分。
- color 00 || echo Failure
- 只有當錯誤級別非零時,無論正負,才會執行 || 後面的部分。
- color 00 || (
echo Failure
)- 多行括號也能正常工作。
- echo %ERRORLEVEL%
- 輸出錯誤級別而不改變它。
- if %errorlevel% equ 0 echo 錯誤級別為零,表示成功。
- if %errorlevel% neq 0 echo 錯誤級別非零,表示失敗。
- if errorlevel 1 echo 錯誤級別 >= 1,表示透過正錯誤級別失敗。
- 不涵蓋透過負錯誤級別失敗的情況。請注意“>=”部分:這與 if %errorlevel% equ 1 不同。
- exit /b 1
- 返回一個批處理檔案,並將錯誤級別設定為 1。
- cmd /c "exit /b 10"
- 在批處理檔案的中間或命令列上,將錯誤級別設定為 10。
- (cmd /c "exit /b 0" && Echo Success) & (cmd /c "exit /b -1" || Echo Failure)
- 如上所示,錯誤級別確實受到影響。
- (cmd /c "exit /b 0" & cmd /c "exit /b 1") || Echo Failure
- 由 & 建立的鏈的錯誤級別是鏈中最後一個命令的錯誤級別。
- cmd /c "exit /b -1" & if not errorlevel 1 echo 可能是成功
- “if not errorlevel 1” 測試,看起來像是測試成功,但在負數上也會透過:它測試“錯誤級別不 >= 1”,也就是“錯誤級別 <= 0”。
- set myerrorlevel=%errorlevel%
- 記住錯誤級別以供以後使用。
- set errorlevel=0
- 應避免:覆蓋內建的 errorlevel 變數。確保後續透過 %ERRORLEVEL% 訪問時返回 0 而不是實際的錯誤級別。
- cmd /c "exit /b 0"
if 1 equ 1 ( cmd /c "exit /b 1" & echo %errorlevel% )- 輸出 0,因為 %errorlevel% 在 cmd /c "exit /b 1" 執行之前就被擴充套件了。
連結
獲取非空變數的子字串
set a=abcdefgh
echo %a:~0,1% & rem from index 0, length 1; result: a
echo %a:~1,1% & rem from index 1, length 1; result: b
echo %a:~0,2% & rem from index 0, length 2; result: ab
echo %a:~1,2% & rem from index 1, length 2; result: bc
echo %a:~1% & rem from index 1 to the end; result: bcdefgh
echo %a:~-1% & rem from index -1 (last char) to the end; result: h
echo %a:~-2% & rem from index -2 (next-to-last) to the end; result: gh
echo %a:~0,-2% & rem from index 0 to index -2, excl.; result: abcdef
echo %a:~0,-1% & rem from index 0 to index -1, excl.; result: abcdefg
echo %a:~1,-1% & rem from index 1 to index -1, excl.; result: bcdefg
測試子字串是否包含
- if not "%a:bc=%"=="%a%" echo yes
- 如果變數 a 包含“bc”作為子字串,則回顯“yes”。
- 此測試是一個技巧,使用了下面討論的字串替換。
- 如果變數包含引號,則此測試不起作用。
測試“以…開頭”
if %a:~0,1%==a echo yes & rem If variable a starts with "a", echo "yes".
if %a:~0,2%==ab echo yes & rem If variable a starts with "ab", echo "yes".
字串替換
set a=abcd & echo %a:c=% & rem replace c with nothing; result: abd
set a=abcd & echo %a:c=e% & rem replace c with e; result: abed;
set a=abcd & echo %a:*c=% & rem replace all up to c with nothing; result: d
rem Above, the asterisk (*) only works at the beginning of the sought pattern.
另請參見 SET 命令的幫助:set /?。
按“ ”、“,”和“;”中的任意一個分割字串:[“空格”、“逗號”和“分號”]:
set myvar=a b,c;d
for %%a in (%myvar%) do echo %%a
按分號分割字串,假設字串不包含引號
@echo off
set myvar=a b;c;d
set strippedvar=%myvar%
:repeat
for /f "delims=;" %%a in ("%strippedvar%") do echo %%a
set prestrippedvar=%strippedvar%
set strippedvar=%strippedvar:*;=%
if not "%prestrippedvar:;=%"=="%prestrippedvar%" goto :repeat
限制
- 上述字串處理不適用於引數變數(%1、%2、…)。
連結
傳遞給批處理指令碼的命令列引數(也稱為命令列引數)可以透過 %1、%2、…、%9 訪問。引數可以超過九個;要訪問它們,請參閱下面如何迴圈遍歷所有引數。
語法 %0 不引用命令列引數,而是引用批處理檔案的名稱。
測試是否提供了第一個命令列引數
if not -%1-==-- echo Argument one provided
if -%1-==-- echo Argument one not provided & exit /b
使用 SHIFT 迴圈遍歷所有命令列引數(對於每個命令列引數,…)
:argactionstart
if -%1-==-- goto argactionend
echo %1 & REM Or do any other thing with the argument
shift
goto argactionstart
:argactionend
使用 SHIFT 迴圈遍歷所有命令列引數,而不修改 %1、%2 等。
call :argactionstart %*
echo Arg one: %1 & REM %1, %2, etc. are unmodified in this location
exit /b
:argactionstart
if -%1-==-- goto argactionend
echo %1 & REM Or do any other thing with the argument
shift
goto argactionstart
:argactionend
exit /b
將命令列引數傳遞到環境變數
setlocal EnableDelayedExpansion
REM Prevent affecting possible callers of the batch
REM Without delayed expansion, !arg%argno%! used below won't work.
set argcount=0
:argactionstart
if -%1-==-- goto argactionend
set /a argcount+=1
set arg%argcount%=%1
shift
goto argactionstart
:argactionend
set argno=0
:loopstart
set /a argno+=1
if %argno% gtr %argcount% goto loopend
echo !arg%argno%! & REM Or do any other thing with the argument
goto loopstart
:loopend
迴圈遍歷所有命令列引數,儘管不是穩健的
for %%i in (%*) do (
echo %%i
)
這看起來很優雅,但並不穩健,會錯誤處理包含萬用字元(*、?)的引數。特別是,上述 for 命令會將包含萬用字元(*、?)的引數替換為與之匹配的檔名,或者如果找不到匹配檔案則將其刪除。儘管如此,只要傳遞的引數不包含萬用字元,上述迴圈就能按預期工作。
以非穩健的方式查詢命令列引數的數量
set argcount=0
for %%i in (%*) do set /a argcount+=1
同樣,這在處理包含萬用字元的引數時不起作用。
最大可能的引數數量大於 4000,這在 Windows Vista 機器上經過實證確定。在 Windows XP 和 Windows 7 上,此數字可能會有所不同。
在將引數傳遞給批處理指令碼時,用於引數分隔的字元如下
- 空格
- 逗號
- 分號
- 等號
- 製表符
因此,以下行傳遞了相同的四個引數
- test.bat a b c d
- test.bat a,b,c,d
- test.bat a, b, c, d
- test.bat a;b;c;d
- test.bat a=b=c=d
- test.bat a b,c;,;=d
是的,即使包含“a b,c;,;=d”的行也傳遞了四個引數,因為分隔符的序列被視為單個分隔符。
要在引數值中包含空格、逗號或分號,可以將值用引號括起來。但是,引號會成為引數值的一部分。要在指令碼中引用引數時刪除封閉的引號,可以使用 #百分號波浪線 中描述的 %~<number>。
在將引數傳遞給呼叫的命令而不是批處理指令碼時,通常需要使用空格將命令與第一個引數分隔開。但是,對於內部命令,如果命令名稱後面的第一個字元是幾個符號之一,包括 .\/ 等,則不需要此分隔符。
- echo.
- 輸出一個換行符。
- tree.
- 失敗:“tree.” 未找到。tree 是一個外部命令。
- dir..
- 列出父目錄的內容。
- cd..
- 將當前目錄更改為父目錄。
- cd\
- 將當前目錄更改為根目錄。
- start.
- 從當前目錄開啟 Windows 資源管理器。
- dir/b/s
- 遞迴列出目錄內容,顯示完整路徑。
連結
許多命令接受檔名萬用字元——不代表自身並能夠匹配一組檔名的字元。
萬用字元
- *(星號):任意字元序列
- ?(問號):單個字元,但不包括句點(“.”),或者如果它是檔名最大無句點部分末尾的一系列問號的一部分,則可能為零個字元;請參閱示例以瞭解說明
示例
- dir *.txt
- 匹配 Myfile.txt、Plan.txt 和任何其他副檔名為 .txt 的檔案。
- dir *txt
- 不需要包含句點。但是,這也將匹配未按句點約定命名的檔案,例如 myfiletxt。
- ren *.cxx *.cpp
- 將所有副檔名為 .cxx 的檔案重新命名為副檔名為 .cpp 的檔案。
- dir a?b.txt
- 匹配檔案 aab.txt、abb.txt、a0b.txt 等。
- 不匹配 ab.txt,因為後跟非問號或句點的問號不能匹配零個字元。
- 不匹配 a.b.txt,因為問號不能匹配句點。
- dir ???.txt
- 匹配 .txt、a.txt、aa.txt 和 aaa.txt 等,因為後跟句點的序列中的每個問號都可以匹配零個字元。
- dir a???.b???.txt???
- 匹配 a.b.txt 等。雖然最後一個問號序列後沒有句點,但它仍然是檔名最大無句點部分末尾的序列。
- dir ????????.txt & @REM 八個問號
- 匹配與 *.txt 相同的檔案,因為每個檔案也有一個短檔名,在 .txt 之前最多有 8 個字元。
短檔名的怪癖:萬用字元匹配同時在長檔名和通常隱藏的 8 個字元 + 句點 + 3 個字元的檔名上執行。這可能導致意外情況。
與某些其他作業系統的 shell 不同,cmd.exe shell 不會自行執行萬用字元擴充套件(將包含萬用字元的模式替換為與該模式匹配的檔名列表)。每個程式都有責任將萬用字元視為萬用字元。這使得諸如“ren *.txt *.bat”這樣的操作成為可能,因為 ren 命令實際上看到了 * 萬用字元而不是與萬用字元匹配的檔案列表。因此,“echo *.txt”不會顯示當前資料夾中與該模式匹配的檔案,而是按字面輸出“*.txt”。另一個結果是,您可以編寫“findstr a.*txt”而不用擔心“a.*txt”部分會被當前資料夾中某些檔案的名稱替換。此外,遞迴“findstr /s pattern *.txt”是可能的,而在某些其他作業系統中,“*.txt”部分將被替換為在當前資料夾中找到的檔名,而忽略巢狀資料夾。
接受萬用字元的命令包括ATTRIB、COPY、DIR、FINDSTR、FOR、REN等。
連結
您可以使用以下方法獲取使用者輸入
當命令列引數包含檔名時,可以使用特殊語法獲取有關該檔案的各種資訊。
以下語法擴充套件到有關作為 %1 傳遞的檔案的各種資訊
| 語法 | 擴充套件結果 | 示例 |
|---|---|---|
| %~1 | %1 無需包含引號 | 未提供 |
| %~f1 | 帶驅動器磁碟機代號的完整路徑 | C:\Windows\System32\notepad.exe |
| %~d1 | 驅動器磁碟機代號 | C |
| %~p1 | 不帶驅動器磁碟機代號的路徑,並在末尾帶反斜槓 | \Windows\System32\ |
| %~n1 | 對於檔案,則為不帶路徑和副檔名的檔名 對於資料夾,則為資料夾名稱 |
notepad |
| %~x1 | 包含句點的檔名副檔名 | .exe |
| %~s1 | 修改 f、n 和 x 以使用短名稱 | C:\PROGRA~2\WINDOW~3\ACCESS~1\wordpad.exe |
| %~a1 | 檔案屬性 | --a------ |
| %~t1 | 檔案的上次修改日期和時間(格式取決於 Windows 的“區域格式”設定) | 02.11.2006 11:45(例如“英語(美國)”格式) |
| %~z1 | 檔案大小 | 151040 |
| %~pn1 | p 和 n 的組合 | \Windows\System32\notepad |
| %~dpnx1 | 多個字母的組合 | C:\Windows\System32\notepad.exe |
| %~$PATH:1 | 在 PATH 變數中存在的資料夾中找到的第一個匹配項的完整路徑,或者在沒有匹配項時為空字串。 | |
| %~n0 | 對 %0 應用 %~n 批處理檔案的無副檔名名稱 |
tildetest |
| %~nx0 | 對 %0 應用 %~nx 批處理檔案的名稱 |
tildetest.bat |
| %~d0 | 對 %0 應用 %~d 批處理檔案的驅動器磁碟機代號 |
C |
| %~dp0 | 對 %0 應用 %~dp 批處理檔案的資料夾,並在末尾帶反斜槓 |
C:\Users\Joe Hoe\ |
相同的語法適用於由FOR命令建立的單字母變數,例如“%%i”。
要從命令行了解此主題,請鍵入“call /?”或“for /?”。
連結
函式(也稱為子程式)可以使用CALL、標籤、SETLOCAL和ENDLOCAL進行模擬。
確定算術冪的函式示例
@echo off
call :power 2 4
echo %result%
rem Prints 16, determined as 2 * 2 * 2 * 2
goto :eof
rem __Function power______________________
rem Arguments: %1 and %2
:power
setlocal
set counter=%2
set interim_product=%1
:power_loop
if %counter% gtr 1 (
set /a interim_product=interim_product * %1
set /a counter=counter - 1
goto :power_loop
)
endlocal & set result=%interim_product%
goto :eof
雖然函式末尾的 goto :eof 實際上並不需要,但在存在多個函式的常規情況下必須存在。
結果應儲存到的變數可以在呼叫行中指定,如下所示
@echo off
call :sayhello result=world
echo %result%
exit /b
:sayhello
set %1=Hello %2
REM Set %1 to set the returning value
exit /b
在上面的示例中,exit /b 用於代替 goto :eof 以達到相同的效果。
此外,請記住等號是分隔引數的一種方法。因此,以下專案實現了相同的功能
- call :sayhello result=world
- call :sayhello result world
- call :sayhello result,world
- call :sayhello result;world
(請參閱命令列引數作為提醒)
連結
批處理指令碼可以使用SET /a 命令執行簡單的 32 位有符號整數算術運算和按位運算。支援的最大整數為 2147483647 = 2 ^ 31 - 1。支援的最小整數為 -2147483648 = - (2 ^ 31),可以使用 set /a num=-2147483647-1 的技巧分配。語法讓人聯想到 C 語言。
算術運算子包括 *、/、 %(模)、+、-。在批處理中,模必須輸入為“%%”。沒有冪運算子。
按位運算子將數字解釋為 32 個二進位制數字的序列。這些是 ~(補碼)、&(與)、|(或)、^(異或)、<<(左移)、>>(算術/帶符號右移)。沒有邏輯/無符號右移和位旋轉運算子。
否定邏輯運算子為 !:它將零轉換為一,將非零轉換為零。
組合運算子為,:它允許在一個 set 命令中進行更多計算。
組合賦值運算子以“+=”為模型,在“a+=b”中表示“a=a+b”。因此,“a-=b”表示“a=a-b”。對於 *=、/=、 %=、&=、^=、|=、<<= 和 >>= 也是如此。
支援運算子的優先順序順序如下
- ( )
- * / % + -
- << >>
- &
- ^
- |
- = *= /= %= += -= &= ^= |= <<= >>=
- ,
文字可以輸入為十進位制(1234)、十六進位制(0xffff,前導 0x)和八進位制(0777,前導 0)。
負整數的內部位表示為二進位制補碼。這提供了對負整數的按位運算、十六進位制文字大於 0x7FFFFFFF 並小於或等於 0xFFFFFFFF 的賦值和算術結果,以及算術運算的溢位和下溢行為。例如,-2147483648 表示為 0x80000000,因此二進位制補碼運算“set /a num=~(-2147483647-1)”產生 2147483647,等於 0x7FFFFFFF(鍵入 set /a num=0x7FFFFFFF 進行檢查)。再舉一個例子,“-2 & 0xF”產生 14,因為 -2 為 0xFFFFFFFE,與 0xF 進行與運算產生 0xE,即 14。雖然最大十進位制文字為 2147483647,但最大十六進位制文字為 0xFFFFFFFF,它被分配為十進位制 -1。類似地,0xFFFFFFFE 被分配為十進位制 -2,依此類推,因此,例如 0xFFFFFFFE - 2 產生 -4。大於 0xFFFFFFFF 的十六進位制文字轉換為 -1,例如 0xFFFFFFFFFFFFFFFF,而大於 2147483647 的十進位制文字會產生錯誤。最小的可表示 32 位有符號整數為 -2147483648;“-2147483648”不能直接分配,因為這被解釋為 -1 * 2147483648,而 2147483648 大於最大十進位制文字 2147483647;但是,-2147483647-1 可以解決此問題,0x80000000 也可以。“-2147483647-2”下溢到最大的正整數 2147483647;類似地,“-2147483647-3”下溢到 2147483646。在另一個方向上,“2147483647+1”溢位到 -2147483648,這對應於在內部位表示上執行加法,就好像它是無符號的一樣;“2147483647+2”溢位到 -2147483647,依此類推。
由於某些運算子對命令直譯器具有特殊含義,因此使用它們的表示式需要用引號括起來,例如
- set /a num="255^127"
- set /a "num=255^127"
- 引號的替代放置。
- set /a num=255^^127
- 使用 ^ 而不是引號轉義 ^。
示例
- set /a n=(2+3)*5
- 執行簡單的計算並將結果儲存到環境變數 n 中。在互動式呼叫(在批處理之外)時,輸出計算結果,否則不輸出任何內容。
- set /a (2+3)*5
- 在互動式呼叫(在批處理之外)時,輸出計算結果,否則不輸出任何內容。不更改任何變數,僅對互動式使用有用。
- set n1=40 & set n2=25
set /a n3=%n1%+%n2%
- 使用標準百分號表示法進行變數擴充套件。
- set n1=40 & set n2=25
set /a n3=n1+n2
- 避免在變數名稱周圍使用百分號表示法,因為對於 /a 來說不需要。
- set /a num="255^127"
- 將“^”括在引號中以防止其對命令直譯器的特殊含義。
- set /a n1 = (10 + 5)/5
- 在 /a 中,= 周圍的空格無關緊要。但是,習慣於它可以讓你在沒有 /a 的情況下編寫“set var = value”,這會設定“var ”的值而不是“var”。
- if 1==1 (set /a n1=(2+4)*5)
- 不起作用:分組括號內的算術括號會導致問題。
- if 1==1 (set /a n1=^(2+4^)*5)
- 使用脫字元 (^) 轉義算術括號可以解決問題,將“n1=2+(4*5)”括在引號中也可以解決問題。
- set /a n1=2+3,n2=4*7
- 執行兩次計算。
- set /a n1=n2=2
- 與 n1=2,n2=2 效果相同。
- set n1=40 & set n2=25 & set /a n3=n1+n2
- 按預期工作。
- set /a n1=2,n2=3,n3=n1+n2
- 按預期工作。
- set n1=40 & set n2=25 & set /a n3=%n1%+%n2%
- 除非之前設定了 n1 和 n2,否則不起作用。變數規範“%n1%”和“%n2%”在第一個 set 命令執行之前就被展開。去掉百分號符號可以使其工作。
- set /a n1=2,n2=3,n3=%n1%+%n2%
- 除非之前設定了 n1 和 n2,否則不起作用,原因與上一個示例中說明的一致。
- set /a n1=0xffff
- 使用十六進位制表示法將 n1 設定為“65535”。
- set /a n1=0777
- 使用八進位制表示法將 n1 設定為“511”。
- set /a n1=0xffffffff
- 將 n1 設定為 -1。
- set /a n1="~0"
- 將 n1 設定為 -1,這與負整數的底層二進位制補碼錶示保持一致。因此,非負整數的按位取反 (~) 會產生負整數。
- set /a "n1=-1>>1"
- 由於“>>”運算子是算術右移,保留了帶符號 32 位整數的底層二進位制表示的最高位,因此輸出 -1 作為結果。請注意,-1 在內部表示為 0xFFFFFFFF。邏輯右移(丟棄最高位的)將導致 0x7FFFFFFF,即最大正 32 位整數。
- set /a "n1=(-1>>1) & 0x7FFFFFFF"
- 透過清除 32 位帶符號整數的底層二進位制表示的最高位來模擬邏輯右移(丟棄最高位的)1 位。
- set /a "n=-1, shiftcount=4, n1=(n>>shiftcount) & (0x7FFFFFFF >> (shiftcount-1))"
- 模擬邏輯右移,適用於 shiftcount > 0 的情況,當右移超過 1 位時,需要清除多個最高位。
- set /a "n1=1<<32"
- 當右運算元為 32 或更高,或為負數時,將產生 0。這與現代 x86 處理器上的左移指令的行為不同,對於 32 位暫存器,該指令會將右運算元遮蔽為 5 位。因此,使用 x86 指令,結果將為 1,因為 32 & 0x1F 為 0。在 C 語言中,結果未定義,實際結果取決於平臺。
- set /a n1=%random%
- 一個偽隨機數,範圍從 0 到 32767 = 2^15-1。
- set /a n1="%random%>>10"
- 一個偽隨機數,範圍從 0 到 31 = 2^5-1。右移運算子丟棄了 15 位中的 10 位,保留了 5 位。
- set /a n1=%random%%50
- 一個偽隨機數,範圍從 0 到 49。使用 % 模運算子。在批處理中,需要使用 %% 進行模運算:set /a n1=%random%%%50。由於模運算的這種特殊用法,結果並非完全均勻;如果第二個模運算運算元(上面為 50)等於 2 的冪,例如 256 = 2^8,則結果是均勻的。
- set /a n1="(%random%<<15)+%random%"
- 一個偽隨機數,範圍從 0 到 1073741823 = 2^30 - 1。將 %random% 單獨產生的兩個 15 位隨機數組合起來,生成一個 30 位隨機數。
- set /a n1="((%random%<<15)+%random%)%1000000"
- 如上所述,但再次使用模運算,這次是為了達到 0 到 999999 的範圍。
一個列印素數的示例計算
@echo off
setlocal
set n=1
:print_primes_loop
set /a n=n+1
set cand_divisor=1
:print_primes_loop2
set /a cand_divisor=cand_divisor+1
set /a cand_divisor_squared=cand_divisor*cand_divisor
if %cand_divisor_squared% gtr %n% echo Prime %n% & goto :print_primes_loop
set /a modulo=n%%cand_divisor
if %modulo% equ 0 goto :print_primes_loop & REM Not a prime
goto :print_primes_loop2
連結
- 設定在 ss64.com
- 設定在 Microsoft
- ss64.com 上的隨機數
- CMD.EXE 解析數字的規則,作者 dbenham,dostips.com
- 按位運算 # 批處理檔案,rosettacode.org
可以使用 #DIR、#FOR、#FINDSTR、#FORFILES 和 #WHERE 查詢檔案。
示例
- dir /b /s *base*.doc*
- 輸出當前資料夾及其子資料夾中所有檔名在副檔名之前包含“base”且副檔名以“doc”開頭(包括“doc”和“docx”)的檔案。這些檔案以完整路徑輸出,每行一個檔案。
- dir /b /s *.txt | findstr /i pers.*doc
- 將輸出檔案及其完整路徑的結果與支援有限正則表示式的 findstr 過濾命令結合起來,形成一種通用而強大的檔案查詢組合,可以透過檔名和目錄名查詢檔案。
- for /r %i in (*) do @if %~zi geq 1000000 echo %~zi %i
- 對於當前資料夾及其子資料夾中大小大於或等於 1,000,000 位元組的每個檔案,輸出檔案大小(以位元組為單位)和檔案的完整路徑。有關 %~zi 中的語法,請參閱 #百分號波浪線。
- forfiles /s /d 06/10/2015 /c "cmd /c echo @fdate @path"
- 對於當前資料夾及其子資料夾中 2015 年 6 月 10 日或之後修改的每個檔案,輸出檔案的修改日期和完整檔案路徑。/d 後面的日期格式特定於區域設定。因此,允許查詢最近修改的檔案。
- (for /r %i in (*) do @echo %~ti :: %i) | findstr 2015.*:
- 遞迴搜尋當前資料夾,輸出最後修改日期在 2015 年的檔案。在檔名之前放置修改日期和時間,後跟雙冒號。只要使用的 Windows 版本和區域設定以包含四位數年份的格式顯示日期,此方法就能正常工作。雙冒號用於確保 findstr 命令匹配日期而不是檔名。
- for /r %i in (*) do @echo %~ti | findstr 2015 >NUL && echo %i
- 如上所述,輸出 2015 年更改的檔案。與上面不同的是,僅輸出檔案,不輸出修改日期。
- findstr /i /s /m cat.*mat *.txt
- 根據檔案內容查詢檔案。在以 .txt 結尾的檔案中執行對正則表示式 cat.*mat 的全文搜尋,並輸出檔名。/m 開關確保僅輸出檔名。
- where *.bat
- 輸出當前目錄和 PATH 中目錄中的所有 .bat 檔案。
當從標準控制檯(在按 Windows + R 後鍵入 cmd.exe 後出現)使用 Windows 命令列時,可以使用多個鍵盤快捷鍵,包括功能鍵。
- Tab:從當前資料夾中的檔名或資料夾名中完成已鍵入字串的相關部分。相關部分通常是最後一個無空格的部分,但使用引號會更改這一點。通常同時考慮檔案和資料夾以進行完成,但 cd 命令僅考慮資料夾。
- 向上和向下箭頭鍵:一次輸入一個命令歷史記錄中的命令。
- Escape:擦除當前正在鍵入的命令列。
- F1:一次輸入一個字元,從命令歷史記錄中輸入單個先前輸入的命令的字元。每次後續按下 F1 都會輸入一個字元。
- F2:要求您鍵入一個字元,然後輸入命令歷史記錄中先前命令的最短字首,該字首不包含鍵入的字元。因此,如果先前命令是 echo Hello world 並且您鍵入了 o,則輸入 ech。
- F3:輸入命令歷史記錄中的單個先前命令。重複按下不會產生進一步的效果。
- F4:要求您鍵入一個字元,然後擦除當前鍵入的字串中從當前游標位置開始、向右繼續並以您輸入的字元(不包括該字元)結束的部分。因此,如果您鍵入 echo Hello world,使用左箭頭鍵將游標置於 H,按 F4 然後按 w,您將得到 echo world。如果您按 F4 然後按 Enter,則會擦除從游標到行尾的文字。
- F5:一次輸入一個命令歷史記錄中的先前命令。
- F6:輸入 Control+Z 字元。
- F7:開啟一個基於字元的彈出視窗,其中包含命令歷史記錄,並允許您使用箭頭鍵和 Enter 選擇命令。在彈出視窗中按 Enter 後,命令將立即執行。
- F8:給定一個已鍵入的字串,一次顯示命令歷史記錄中以該字串作為字首的專案。
- F9:允許您輸入命令歷史記錄中命令的編號,然後執行該命令。
- Alt + F7:擦除命令歷史記錄。
以上也稱為命令提示符鍵盤快捷鍵。
這些快捷鍵的可用性似乎不依賴於執行 DOSKEY。
連結
檔案和目錄路徑遵循某些約定。這些約定包括可能使用驅動器號後跟冒號 (:)、使用反斜槓 (\) 作為路徑分隔符以及區分相對路徑和絕對路徑。
正斜槓 (/) 通常可以用作 (\) 的替代,但並非總是如此;它通常用於標記開關(選項)。使用正斜槓可能導致各種模糊的行為,最好避免。
特殊裝置名稱包括 NUL、CON、PRN、AUX、COM1、...、COM9、LPT1、...、LPT9;這些可以重定向到。
示例
- attrib C:\Windows\System32\notepad.exe
- 如果檔案存在,則成功,這應該是正確的。這是一個帶有驅動器號的絕對路徑。它也稱為完全限定路徑。
- attrib \Windows\System32\notepad.exe
- 如果當前驅動器為 C: 且檔案存在,則成功,這應該是正確的。這是一個沒有驅動器號的絕對路徑。
- cd /d C:\Windows & attrib System32\notepad.exe
- 如果檔案存在,則成功。傳遞給 attrib 的路徑是相對路徑。
- cd /d C:\Windows\System32 & attrib C:notepad.exe
- 如果檔案存在,則成功。傳遞給 attrib 的路徑是相對路徑,儘管包含驅動器號:必須存在帶有反斜槓的 C:\notepad.exe 才能使其成為絕對路徑。
- cd /d C:\Windows & attrib .\System32\notepad.exe
- 如果檔案存在,則成功。單個句點表示當前資料夾。
- attrib .
- 單個句點表示當前資料夾。
- cd /d C:\Windows & attrib .\System32\\\notepad.exe
- 如果檔案存在,則成功。反斜槓的堆疊除了第一個反斜槓之外沒有其他影響。
- cd /d C:\Windows & attrib .\System32
- 如果資料夾存在則成功。
- cd /d C:\Windows & attrib .\System32\
- 失敗。資料夾通常不帶最後的反斜槓表示。
- cd C:\Windows\System32\
- 成功,無論如何。
- cd ..
- 雙點表示父資料夾。
- attrib C:\Windows\System32\..\..\Windows\System32
- 雙點可以用於路徑中間,以導航到父資料夾,甚至多次。
- attrib \\myserver\myvolume
- 網路 UNC 路徑以雙反斜槓開頭,沒有驅動器號。
- cd \\myserver\myvolume
- 不起作用;以這種直接方式更改到伺服器資料夾不起作用。
- pushd \\myserver\folder
- 自動為資料夾建立驅動器並切換到該驅動器。使用#POPD後,驅動器將再次取消分配。
- attrib C:/Windows/System32/notepad.exe
- 在多個版本的 cmd.exe 上成功。使用正斜槓。
連結
- 長檔名、NTFS 和 ss64.com 上的合法檔名字元
- Microsoft 上的檔案、路徑和名稱空間命名
- W:路徑(計算)#MS-DOS/Microsoft Windows 樣式,wikipedia.org
- 為什麼 Windows 上的 cmd.exe shell 使用正斜槓 ('/) 路徑分隔符的路徑會失敗?,stackoverflow.com
在延遲擴充套件模式下,可以使用 % 和 ! 的組合來模擬陣列,以指示變數。其中,%i% 是變數 i 的值,使用立即擴充套件,而 !i! 是變數 i 的值,使用延遲擴充套件。
@echo off
setlocal EnableDelayedExpansion
for /l %%i in (1, 1, 10) do (
set array_%%i=!random!
)
for /l %%i in (1, 1, 10) do (
echo !array_%%i!
)
:: For each item in the array, not knowing the length
set i=1
:startloop
if not defined array_%i% goto endloop
set array_%i%=!array_%i%!_dummy_suffix
echo A%i%: !array_%i%!
set /a i+=1
goto startloop
:endloop
連結
- cmd.exe(批處理)指令碼中的陣列、連結列表和其他資料結構,stackoverflow.com
一些任務可以透過 Perl 單行命令方便地完成。Perl 是一種源自其他作業系統的環境的指令碼語言。由於許多 Windows 計算環境都安裝了 Perl,因此 Perl 單行命令是 Windows 批處理指令碼的自然且緊湊的擴充套件。
示例
- echo "abcbbc"| perl -pe "s/a.*?c/ac/"
- 讓 Perl 充當 sed,該實用程式支援使用正則表示式指定的文字替換。
- echo a b| perl -lane "print $F[1]"
- 讓 Perl 充當 cut 命令,顯示該行的第 2 個欄位或列,在本例中為 b。使用 $F[2] 顯示第 3 個欄位;索引從零開始。原生解決方案:FOR /f。
- perl -ne "print if /\x22hello\x22/" file.txt
- perl -ne "$. <= 10 and print" MyFile.txt
- 讓 Perl 充當 head -10 命令,輸出檔案的前 10 行。
- perl -e "sleep 5"
- 等待 5 秒。
- for /f %i in ('perl -MPOSIX -le "print strftime '%Y-%m-%d', localtime"') do @set isodate=%i
- 以 ISO 格式獲取當前日期到 isodate 變數中。
- perl -MWin32::Clipboard -e "print Win32::Clipboard->Get()"
- 輸出剪貼簿的文字內容。儲存到 getclip.bat 時,會生成一個方便的 getclip 命令來補充 CLIP 命令。
- perl -MText::Diff -e "print diff 'File1.txt', 'File2.txt'"
- 以類似於其他作業系統中已知的 diff 命令的格式輸出兩個檔案之間的差異,包括上下文行、以 + 開頭的行和以 - 開頭的行。
- perl -MWin32::Sound -e "Win32::Sound::Play('C:\WINDOWS\Media\notify.wav');"
- 播放 notify.wav 中的通知聲音,不顯示任何視窗。
在網路上,Perl 單行命令通常以其他作業系統的命令列約定釋出,包括使用撇號 (') 而不是 Windows 引號來包圍引數。這些需要針對 Windows 進行調整。
連結
Windows cmd.exe 命令直譯器可以使用來自類 Unix 作業系統的命令,前提是已安裝這些命令。示例命令包括 grep、sed、awk、wc、head 和 tail。這些命令來自 GNU 專案,並且存在它們的 Windows 埠。您可以在 Unix 指南 Wikibook 中瞭解更多關於這些命令的資訊。請注意,依賴於這些命令的批處理程式不能保證在其他 Windows 機器上執行。
可以從以下專案中獲得免費許可的 Windows 版本的 GNU 命令
- GnuWin32,sourceforge.net
- ezwinports,sourceforge.net:有一些比 GnuWin32 更新的埠
在 Windows 10 上執行 GNU 命令的另一種方法是 Windows 子系統 Linux。
沒有其他作業系統中常見的 touch 命令。touch 命令將在不更改檔案內容的情況下修改檔案的上次修改時間戳。
一種解決方法,其可靠性和跨不同 Windows 版本的適用性尚不清楚,如下所示
- copy /b file.txt+,,
連結
- Windows 遞迴 touch 命令 在 superuser.com 上
- Unix touch 命令的 Windows 版本 在 stackoverflow.com 上
沒有內建命令來獲取檔案的最後幾行;沒有 tail 命令的等價物。但是,可以編寫批處理來完成這項工作,並且可以從下面的連結獲得。或者,可以為 Windows 安裝 tail 命令,或者執行不需要安裝的 PowerShell 等價物。
連結
- CMD.EXE 批處理指令碼以顯示 txt 檔案中的最後 10 行,stackoverflow.com
沒有預安裝的十六進位制轉儲工具來檢視檔案內容的十六進位制表示。儘管如此,還有以下選項
1) 使用fsutil file createnew 建立一個全零位元組的檔案,並使用fc 透過比較來檢視位元組
- fsutil file createnew allzeros.bin 1000
fc /b C:\Windows\notepad.exe allzeros.bin- 在比較中不會顯示 notepad.exe 的零位元組,但其他位元組將顯示其偏移量,每行一個位元組。您可以透過選擇全零位元組檔案的長度來確定要檢視多少個初始位元組,方法是更改上面的最後一個 1000。要檢視完整的檔案,請建立與要檢查的檔案長度相同的全零位元組檔案。遠非完美,但可以用作快速解決方法來檢視例如 BOM 標記或使用的換行符型別。
2) 使用 certutil -encodeHex,其中 encodeHex 功能未正式記錄
- certutil -encodeHex file.txt filehex.txt
- 將 file.txt 的檔案內容以十六進位制寫入 filehex.txt。如果 filehex.txt 存在,則拒絕覆蓋它。您無法限制要轉換的位元組數。
3) 使用 PowerShell 5.0 Format-Hex
- powershell Format-Hex C:\Windows\notepad.exe
- 在最新的 PowerShell 中支援 Option -Count。
4) 安裝一個命令,例如功能豐富的od 或hexdump;見 Unix 命令。od 也可以進行八進位制轉儲。
5) 如果您使用的是舊版 32 位 Windows(不太可能),請使用debug;見 DEBUG。
連結
- fc,docs.microsoft.com
- certutil,ss64.com
- certutil,docs.microsoft.com
- Format-Hex,docs.microsoft.com
- Dave Benham 的 HEXDUMP.BAT 版本 2.1 使用 CERTUTIL,dostips.com
- 新函式 - :hexDump 由 Dave Benham,dostips.com - 純批處理;大量的批處理魔法,而且速度很慢
如果您的使用者具有提升的管理許可權,則可以在以特定方式啟動 cmd.exe 時使用這些許可權。要以提升的許可權啟動 cmd.exe,您可以執行以下操作。
- 選擇“開始”選單,並在其中鍵入“cmd.exe”。
- 右鍵單擊 cmd.exe 圖示,然後選擇“以管理員身份執行”。
要測試您是否具有提升的許可權
- 執行“net session”,如果您沒有許可權,則此命令將失敗。
限制包括以下內容
- 沒有 while 迴圈;可以透過標籤和 goto 模擬。有一個 for 迴圈和一個 if 語句。
- 沒有 C 語言中已知的用於迴圈控制的 break 和 continue 語句。
- 沒有合適的自定義函式;可以使用標籤、call 和 %n 引數擴充套件來建立自定義函式。
- 對包含特殊字元(如引號(")或&號(&))的字串進行脆弱的處理。
- 不支援陣列;可以有限地進行模擬。
- 不支援關聯陣列,也稱為字典。
- 不支援浮點運算。
- 不支援 C 語言中的三元條件運算子。
- 沒有將字元轉換為其 ASCII 值或將 ASCII 值轉換為字元的函式。沒有合理的變通方法。
- 不支援任意大小的整數運算。
- 不支援來自其他作業系統的更改檔案時間戳的 touch 命令;也不支援 head 和 tail 命令。
- 不支援 GUI 程式設計。
- 以及更多。
這些命令都內置於命令直譯器本身,無法更改。有時這是因為它們需要訪問內部命令直譯器資料結構,或修改命令直譯器程序本身的屬性。
| 命令 | 描述 |
|---|---|
| ASSOC | 將副檔名與檔案型別 (FTYPE) 關聯。 |
| BREAK | 設定或清除擴充套件的 CTRL+C 檢查。 |
| CALL | 從另一個批處理程式呼叫一個批處理程式。 |
| CD,CHDIR | 輸出或設定當前目錄。 |
| CHCP | 輸出或設定活動內碼表編號。 |
| CLS | 清除螢幕。 |
| COLOR | 設定控制檯的前景色和背景色。 |
| COPY | 複製檔案。 |
| DATE | 輸出並設定系統日期。 |
| DEL,ERASE | 刪除一個或多個檔案。 |
| DIR | 輸出目錄中的檔案和子目錄列表。 |
| ECHO | 輸出訊息,或開啟或關閉命令回顯。 |
| ELSE | 當 "IF" 不為真時,在批處理程式中執行條件處理。 |
| ENDLOCAL | 結束批處理檔案中環境更改的本地化。 |
| EXIT | 退出 CMD.EXE 程式(命令直譯器)。 |
| FOR | 對一組檔案中的每個檔案執行指定的命令。 |
| FTYPE | 設定檔案型別命令。 |
| GOTO | 轉到標籤。 |
| IF | 在批處理程式中執行條件處理。 |
| MD,MKDIR | 建立目錄。 |
| MOVE | 將檔案移動到新位置 |
| PATH | 設定或修改 PATH 環境 |
| PAUSE | 使命令會話暫停以等待使用者輸入。 |
| POPD | 更改為從目錄堆疊中彈出的驅動器和目錄 |
| PROMPT | 設定或修改等待輸入時顯示的字串。 |
| PUSHD | 將當前目錄推入堆疊,並更改為新目錄。 |
| RD / RMDIR | 刪除目錄。 |
| REM | 註釋命令。與雙冒號 (::) 不同,該命令可以執行。 |
| REN / RENAME | 重新命名檔案或目錄。 |
| SET | 設定或輸出 shell 環境變數。 |
| SETLOCAL | 為批處理檔案建立子環境。 |
| SHIFT | 將批處理引數向前移動。 |
| START | 使用各種選項啟動程式。 |
| TIME | 輸出或設定系統時鐘。 |
| TITLE | 更改視窗標題 |
| TYPE | 將檔案內容列印到控制檯。 |
| VER | 顯示命令處理器、作業系統版本。 |
| VERIFY | 驗證檔案複製是否已正確完成。 |
| VOL | 顯示當前卷的標籤。 |
將副檔名與檔案型別 (FTYPE) 關聯,輸出現有關聯或刪除關聯。另請參閱 FTYPE。
示例
- assoc
- 列出所有關聯,格式為“<副檔名>=<檔案型別>” ,例如“.pl=Perl”或“.xls=Excel.Sheet.8”。
- assoc | find ".doc"
- 列出所有包含“.doc”子字串的關聯。
連結
在基於 Windows NT 的 Windows 版本中,不執行任何操作;保留以與 MS DOS 保持相容性。
示例
- break > empty.txt
- 建立空檔案或清除現有檔案的內容,利用 break 不執行任何操作且沒有輸出這一事實。比“type nul > empty.txt”鍵入更短。
連結
從另一個批處理程式呼叫一個批處理程式,在單個批處理程式中呼叫子程式,或者,作為未記錄的行為,啟動程式。特別是,掛起呼叫者的執行,開始執行被呼叫者,並在被呼叫者完成執行時恢復呼叫者的執行。
有關呼叫子程式,請參閱 函式 部分。
請注意,在不使用 call 關鍵字的情況下從批處理中呼叫批處理會導致執行在被呼叫者完成時永遠不會返回到呼叫者。
被呼叫者繼承呼叫者的環境變數,並且除非被呼叫者透過 SETLOCAL 阻止這種情況,否則被呼叫者對環境變數所做的更改在恢復執行後將對呼叫者可見。
示例
- mybatch.bat
- 如果在批處理中使用,則將控制權轉移到 mybatch.bat 並且永遠不會恢復呼叫者的執行。
- call mybatch.bat
- call mybatch
- call mybatch.bat arg1 "arg 2"
- call :mylabel
- call :mylabel arg1 "arg 2"
- cmd /c mybatch.bat
- 類似於 call,但即使出現錯誤也會恢復執行。此外,被呼叫者對環境變數所做的任何更改都不會傳播到呼叫者。
- call notepad.exe
- 啟動記事本,或一般來說,任何其他可執行檔案。這顯然不是 call 的預期用法,並且沒有正式記錄。
連結
- ss64.com 上的 call
- Microsoft 上的 call
- CALL 命令與帶有 /WAIT 選項的 START 命令,stackoverflow.com
更改到不同的目錄,或輸出當前目錄。但是,如果使用了不同的驅動器號,它不會切換到該不同的驅動器或卷。
示例
- cd
- 輸出當前目錄,例如 C:\Windows\System32。
- cd C:\Program Files
- 路徑中包含空格時,不需要使用引號括起來。
- cd \Program Files
- cd Documents
- cd %USERPROFILE%
- cd /d C:\Program Files
- 即使 C: 不是當前驅動器,也會更改到 C: 驅動器的目錄。
- C: & cd C:\Program Files。
- 即使 C: 不是當前驅動器,也會更改到 C: 驅動器的目錄。
- cd ..
- 更改到父目錄。如果已經在根目錄中,則不執行任何操作。
- cd ..\..
- 更改到上兩級的父目錄。
- C: & cd C:\Windows\System32 & cd ..\..\Program Files
- 使用“..”在目錄樹中向上和向下導航
- cd \\myserver\folder
- 不起作用。無法直接將目錄更改為網路通用命名約定 (UNC) 資料夾。關鍵字:UNC 路徑。
- subst A: \\myserver\folder && cd /d A
- 使用 #SUBST 命令將目錄更改為伺服器資料夾,假設驅動器號 A: 是空閒的。
- pushd \\myserver\folder
- 自動為資料夾建立驅動器並切換到該驅動器。使用#POPD後,驅動器將再次取消分配。
- cd C:\W*
- 在典型的 Windows 設定中更改為 C:\Windows。因此,萬用字元有效。對從命令列手動鍵入很有用。
- cd C:\W*\*32
- 在典型的 Windows 設定中更改為 C:\Windows\System32。
連結
是 CD 的同義詞。
清除螢幕。
設定控制檯的前景色和背景色。
示例
- color f9
- 使用白色背景和藍色前景色。
- color
- 恢復原始顏色設定。
連結
複製檔案。另請參閱 MOVE、XCOPY 和 ROBOCOPY。
示例
- copy F:\File.txt
- 複製檔案到當前目錄,假設當前目錄不是 F:\。
- copy "F:\My File.txt"
- 同上;需要用引號括住包含空格的檔名。
- copy F:\*.txt
- 將位於 F:\ 且以 .txt 結尾的檔案複製到當前目錄,假設當前目錄不是 F:\。
- copy F:\*.txt .
- 與上一條命令相同。
- copy File.txt
- 顯示錯誤訊息,因為 File.txt 不能覆蓋自身。
- copy File1.txt File2.txt
- 將 File1.txt 複製到 File2.txt,如果使用者確認或從批處理指令碼執行則覆蓋 File2.txt。
- copy File.txt "My Directory"
- 將 File.txt 複製到 "My Directory" 目錄,假設 "My Directory" 目錄存在。
- copy Dir1 Dir2
- 將目錄 Dir1 中直接位於該目錄下的所有檔案複製到 Dir2,假設 Dir1 和 Dir2 都是目錄。不會複製 Dir1 的巢狀目錄中的檔案。
- copy *.txt *.bak
- 對於當前資料夾中的每個 *.txt 檔案,建立一個以 "bak" 而不是 "txt" 結尾的副本。
連結
刪除檔案。謹慎使用,尤其是在與萬用字元結合使用時。僅刪除檔案,不刪除目錄,有關目錄的刪除,請參閱 RD。更多資訊,請鍵入 "del /?"。
示例
- del File.txt
- del /s *.txt
- 遞迴刪除檔案,包括巢狀目錄,但保留目錄;無情地刪除所有匹配的檔案,無需確認。
- del /p /s *.txt
- 同上,但在刪除每個檔案之前都要求確認。
- del /q *.txt
- 刪除檔案,無需確認。
連結
列出目錄的內容。提供一系列選項。鍵入 "dir /?" 獲取更多幫助。
示例
- dir
- 列出當前資料夾中的檔案和資料夾,不包括隱藏檔案和系統檔案;如果 DIRCMD 變數非空且包含 dir 的開關,則使用不同的列出方式。
- dir D
- dir /b C:\Users
- dir /s
- 遞迴列出目錄及其所有子目錄的內容。
- dir /s /b
- 遞迴列出目錄及其所有子目錄的內容,每行一個檔案,顯示每個列出的檔案或目錄的完整路徑。
- dir *.txt
- 列出所有副檔名為 .txt 的檔案。
- dir /a
- 在列表中包含隱藏檔案和系統檔案。
- dir /ah
- 僅列出隱藏檔案。
- dir /ad
- 僅列出目錄。/A 後面的其他字母包括 S、I、R、A 和 L。
- dir /ahd
- 僅列出隱藏目錄。
- dir /a-d
- 僅列出檔案,省略目錄。
- dir /a-d-h
- 僅列出非隱藏檔案,省略目錄。
- dir /od
- 按上次修改日期對檔案和資料夾進行排序。/O 後面的其他字母包括 N(按名稱)、E(按副檔名)、S(按大小)和 G(資料夾優先)
- dir /o-s
- 按大小降序排列檔案;對資料夾順序的影響尚不清楚。
- dir /-c /o-s /a-d
- 列出按大小降序排列的檔案,透過 /-C 省略千位分隔符,排除資料夾。
- dir /s /b /od
- 遞迴列出目錄及其所有子目錄的內容,按上次修改日期對每個目錄中的檔案進行排序。排序僅在每個目錄中進行;如此找到的檔案的完整集合不會整體排序。
- dir /a /s
- 遞迴列出檔案,包括隱藏檔案和系統檔案。可以透過考慮輸出的最後幾行來計算磁碟使用情況(目錄大小)。
連結
輸出或設定日期。日期的輸出方式取決於國家/地區設定。日期也可以使用 "echo %DATE%" 輸出。
獲取 ISO 格式的日期,例如 "2000-01-28":這並不容易,因為日期格式取決於國家/地區設定。
- 如果您可以假設格式為 "Mon 01/28/2000",則以下程式碼將起作用
- set isodate=%date:~10,4%-%date:~4,2%-%date:~7,2%
- 如果您有 WMIC,則以下程式碼與區域設定無關
- for /f %i in ('wmic os get LocalDateTime') do @if %i lss a if %i gtr 0 set localdt=%i
set isodate=%localdt:~0,4%-%localdt:~4,2%-%localdt:~6,2% - 要在批處理中使用上述程式碼,請將 %i 更改為 %%i 並從 if 前面的 @ 中刪除 @。
- for /f %i in ('wmic os get LocalDateTime') do @if %i lss a if %i gtr 0 set localdt=%i
- 如果您安裝了 Perl
- for /f %i in ('perl -MPOSIX -le "print strftime '%Y-%m-%d', localtime"') do @set isodate=%i
連結
- date 在 ss64.com 上
- date 在 Microsoft 上
- 如何在 Windows 命令列中獲取當前日期時間,並以適合用作檔名格式的格式輸出? 在 stackoverflow 上
輸出訊息,或開啟或關閉命令回顯。
示例
- echo on
- @echo off
- echo Hello
- echo "hello"
- 也輸出引號。
- echo %PATH%
- 輸出 PATH 變數的內容。
- echo Owner ^& son
- 使用脫字元 (^) 轉義與號 (&),從而能夠回顯與號。
- echo 1&echo 2&echo 3
- 輸出三個字串,每個字串後面跟著一個換行符。
- echo.
- 輸出一個換行符,而句點不被輸出。如果沒有句點,則輸出 "echo off" 或 "echo on"。在句點前面新增一個空格會導致句點被輸出。其他與句點具有相同效果的字元包括 ;:,/\(=+[].
- echo %random%>>MyRandomNumbers.txt
- 雖然它似乎將隨機數輸出到 MyRandomNumbers.txt,但實際上它不會對 0-9 的數字這樣做,因為這些數字放在 >> 前面時,表示要重定向哪個通道。另請參閱 #Redirection。
- echo 2>>MyRandomNumbers.txt
- 不回顯 2,而是將標準錯誤重定向到檔案。
- (echo 2)>>MyRandomNumbers.txt
- 即使是小的數字(在本例中為 2)也會回顯並重定向結果。
- >>MyRandomNumbers.txt echo 2
- 另一種回顯即使是小的數字並重定向結果的方法。
顯示不帶換行符的字串需要一個技巧
- set <NUL /p=Output of a command
- 輸出 "Output of a command:"。下一個命令的輸出將緊跟在 ":" 後面顯示。
- set <NUL /p=Current time: & time /t
- 輸出 "Current time: " 後跟 "time /t" 的輸出。
- (set <NUL /p=Current time: & time /t) >tmp.txt
- 與之前一樣,將兩個命令的輸出都重定向到檔案。
連結
一個例子
if exist file.txt (
echo The file exists.
) else (
echo The file does not exist.
)
另請參閱 IF。
結束使用 SETLOCAL 啟動的本地環境變數集。可用於建立子程式:請參閱 Functions。
連結
DEL 的同義詞。
退出 DOS 控制檯,或者使用 /b 僅退出當前執行的批處理或當前執行的子例程。如果在批處理檔案中不帶 /b 使用,則會導致呼叫批處理的 DOS 控制檯關閉。
示例
- exit
- exit /b
連結
迭代一系列值,執行命令。關鍵字:迴圈。
在以下示例中,%i 用於命令列,而 %%i 用於批處理。索引(例如,%i)必須是單字元變數名。
不帶開關和帶 /r 和 /d 開關的示例
- for %%i in (1,2,3) do echo %%i
- 在批處理中,回顯 1、2 和 3。在批處理中,命令必須使用雙百分號。
- 其餘示例旨在直接貼上到命令列中,因此它們使用單個百分號幷包含 "@" 以防止重複顯示。
- for %i in (1,2,3) do @echo %i
- 從命令列回顯 1、2 和 3。
- for 命令嘗試將專案解釋為檔名和包含萬用字元的檔名模式。
- 但是,如果專案與現有檔名不匹配,它不會報錯。
- for %i in (1,2,a*d*c*e*t) do @echo %i
- 除非您碰巧有一個與第三個模式匹配的檔案,否則回顯 1 和 2,丟棄第三個專案。
- for %i in (1 2,3;4) do @echo %i
- 回顯 1、2、3 和 4。是的,使用了專案分隔符的混合。
- for %i in (*.txt) do @echo %i
- 回顯位於當前資料夾中且副檔名為 .txt 的檔案的檔名。
- for %i in ("C:\Windows\system32\*.exe") do @echo %i
- 回顯與模式匹配的檔名。
- for /r %i in (*.txt) do @echo %i
- 回顯具有完整路徑的檔名,這些副檔名為 .txt,位於當前資料夾的任何位置,包括巢狀資料夾。
- for /d %i in (*) do @echo %i
- 回顯當前資料夾中所有資料夾的名稱。
- for /r /d %i in (*) do @echo %i
- 回顯當前資料夾中所有資料夾(包括巢狀資料夾)的名稱,包括完整路徑。
- for /r %i in (*) do @if %~zi geq 1000000 echo %~zi %i
- 對於當前資料夾及其子資料夾中大小大於或等於 1,000,000 位元組的每個檔案,輸出檔案大小(以位元組為單位)和檔案的完整路徑。有關 %~zi 中的語法,請參閱 #百分號波浪線。
/l 開關的示例
- for /l %i in (1,2,11) do @echo %i
- 以步長為 2,輸出從 1 到 11 的數字。格式為 (起始值, 步長, 結束值)。支援 32 位有符號整數。
- for /l %i in (10,-1,1) do @echo %i
- 輸出從 10 到 1 的降序數字。
- for /l %i in (1,0,1) do @echo %i
- 持續輸出 1;一個無限迴圈。
- for /l %i in (0) do @echo %i
- 持續輸出 0;一個無限迴圈。
- for /l %i in () do @echo %i
- 持續輸出 0;一個無限迴圈。
- for /l %i in (-10,1) do @echo %i
- 輸出從 -10 到 0 的數字;未明確指定的結束值預設為零。
- for /l %i in (0xF, 1, 020) do @echo %i
- 輸出從 15 到 16 的數字;因此,支援十六進位制和八進位制字面量。
- for /l %i in (2147483646,1,2147483647) do @echo %i
- 輸出 2147483646,然後 2147483647,然後 -2147483648,然後 -2147483647,依此類推。這可能是由於 2147483647 的增量溢位到 -2147483648 造成的。
- for /l %i in (-2147483648,1,-2147483647) do @echo %i
- 輸出 -2147483648 和 -2147483647。因此,直接支援 -2147483648 字面量,不像 set /a。
/f 開關的示例
- for /f "tokens=*" %i in (list.txt) do @echo %i
- 對於檔案中的每一行,輸出該行。
- for /f "tokens=*" %i in (list1.txt list2.txt) do @echo %i
- 對於檔案中的每一行,輸出該行。
- for /f "tokens=*" %i in (*.txt) do @echo %i
- 不執行任何操作。不接受用於匹配檔名的萬用字元。
- for /f "tokens=1-3 delims=:" %a in ("First:Second::Third") do @echo %c-%b-%a
- 將字串解析為以“:”分隔的標記。
- 引號表示該字串不是檔名。
- 即使在命令的“do”之前的部分沒有明確提及 %b 和 %c,第二個和第三個標記也會儲存在 %b 和 %c 中。
- 兩個連續的冒號被視為一個分隔符;%c 不是 "",而是 "Third"。
- 執行其他作業系統中 cut 命令的部分功能。
- for /f "tokens=1-3* delims=:" %a in ("First:Second::Third:Fourth:Fifth") do @echo %c-%b-%a: %d
- 與上面相同,只是第 4 和第 5 個專案被捕獲到 %d 中,包括分隔符,即 "Fourth:Fifth"。
- for /f "tokens=1-3* delims=:," %a in ("First,Second,:Third:Fourth:Fifth") do @echo %c-%b-%a: %d
- 可以有多個分隔符。
- for /f "tokens=1-3" %a in ("First Second Third,item") do @echo %c-%b-%a
- 預設分隔符是空格和製表符。因此,它們與傳遞給批處理的引數的分隔符不同。
- for /f "tokens=*" %i in ('cd') do @echo %i
- 對於命令結果的每一行,輸出該行。
- for /f "tokens=*" %i in ('dir /b /a-d-h') do @echo %~nxai
- 對於當前資料夾中的每個非隱藏檔案,輸出檔案屬性,後跟檔名。在字串 "%~nxai" 中,使用 #Percent tilde 中描述的語法。
- for /f "usebackq tokens=*" %i in (`dir /b /a-d-h`) do @echo %~nxai
- 與上面相同,但使用反引號字元 (`) 將要執行的命令括起來。
- for /f "tokens=*" %i in ('tasklist ^| sort ^& echo End') do @echo %i
- 要執行的命令中的管道和與號必須使用脫字元 (^) 進行轉義。
重定向示例
- (for %i in (1,2,3) do @echo %i) > anyoldtemp.txt
- 要重定向 for 迴圈的整個結果,請在重定向之前將整個迴圈放在括號中。否則,重定向將繫結到迴圈體,因此迴圈體的每次新迭代都將覆蓋先前迭代的結果。
- for %i in (1,2,3) do @echo %i > anyoldtemp.txt
- 與上面相關的示例。它顯示了未將迴圈放在括號中的後果。
繼續: 要跳轉到迴圈的下一輪迭代並模擬許多語言中已知的 continue 語句,您可以使用 goto,前提是您將迴圈體放在一個子例程中,如下所示
for %%i in (a b c) do call :for_body %%i
exit /b
:for_body
echo 1 %1
goto :cont
echo 2 %1
:cont
exit /b
如果您直接在 for 迴圈內部使用 goto,則 goto 的使用會破壞迴圈簿記。以下操作失敗
for %%i in (a b c) do (
echo 1 %%i
goto :cont
echo 2 %%i
:cont
echo 3 %%i
)
連結
- for 在 ss64.com 上
- Microsoft 上的 for
- CMD.EXE 解析數字的規則,作者 dbenham,dostips.com
輸出或設定要為檔案型別執行的命令。另請參見 ASSOC。
示例
- ftype
- 列出所有與檔案型別關聯的要執行的命令,例如“Perl="C:\Perl\bin\perl.exe" "%1" %*”
- ftype | find "Excel.Sheet"
- 僅列出顯示行包含“Excel.Sheet”的關聯。
連結
轉到標籤。
一個例子
goto :mylabel
echo Hello 1
REM Hello 1 never gets printed.
:mylabel
echo Hello 2
goto :eof
echo Hello 3
REM Hello 3 never gets printed. Eof is a virtual label standing for the end of file.
在 for 迴圈體中使用 goto 會使 cmd 忘記迴圈,即使標籤在同一個迴圈體中。
連結
有條件地執行命令。透過在 CMD 提示符下輸入 IF /? 可以檢視文件。
可用的基本測試
- exist <檔名>
- <字串>==<字串>
- <表示式1> equ <表示式2> -- 等於
- <表示式1> neq <表示式2> -- 不等於
- <表示式1> lss <表示式2> -- 小於
- <表示式1> leq <表示式2> -- 小於或等於
- <表示式1> gtr <表示式2> -- 大於
- <表示式1> geq <表示式2> -- 大於或等於
- defined <變數>
- errorlevel <數字>
- cmdextversion <數字>
可以對每個基本測試應用“not”。顯然,沒有像 AND、OR 等運算子來組合基本測試。
/I 開關使 == 和 equ 比較忽略大小寫。
一個例子
if not exist %targetpath% (
echo Target path not found.
exit /b
)
示例
- if not 1 equ 0 echo Not equal
- if 1 equ 0 echo A & echo B
- 不執行任何操作;兩個 echo 命令都受條件約束。
- if not 1 equ 0 goto :mylabel
- if not a geq b echo Not greater
- if b geq a echo Greater
- if b geq A echo Greater in a case-insensitive comparison
- if B geq a echo Greater in a case-insensitive comparison
- if 0 equ 00 echo Numerical equality
- if not 0==00 echo String inequality
- if 01 geq 1 echo Numerical comparison
- if not "01" geq "1" echo String comparison
- if 1 equ 0 (echo Equal) else echo Unequal
- 注意 then 部分周圍的括號,以使其正常工作。
- if not a==A echo Case-sensitive inequality
- if /i a==A echo Case-insensitive equality
- if /i==/i echo This does not work
- if "/i"=="/i" echo Equal, using quotation marks to prevent the literal meaning of /i
連結
建立新目錄或目錄。具有同義詞 MKDIR;另請參見其反義詞 RD。
示例
- md Dir
- 在當前目錄中建立一個目錄。
- md Dir1 Dir2
- 在當前目錄中建立兩個目錄。
- md "My Dir With Spaces"
- 在當前目錄中建立名稱包含空格的目錄。
連結
MD 的同義詞。
建立符號連結或其他型別的連結。自 Windows Vista 起可用。
連結
在目錄之間移動檔案或目錄,或重新命名它們。另請參見 REN。
示例
- move File1.txt File2.txt
- 將 File1.txt 重新命名為 File2.txt,如果使用者確認或從批處理指令碼執行,則覆蓋 File2.txt。
- move File.txt Dir
- 將 File.txt 檔案移動到 Dir 目錄中,假設 File.txt 是檔案,Dir 是目錄;如果滿足覆蓋條件,則覆蓋目標檔案 Dir\a.txt。
- move Dir1 Dir2
- 將目錄 Dir1 重新命名為 Dir2,假設 Dir1 是目錄,Dir2 不存在。
- move Dir1 Dir2
- 將目錄 Dir1 移動到 Dir2 中,導致 Dir2\Dir1 存在,假設 Dir1 和 Dir2 都是現有目錄。
- move F:\File.txt
- 將檔案移動到當前目錄。
- move F:\*.txt
- 將位於 F:\ 並以點 txt 結尾的檔案移動到當前目錄,假設當前目錄不是 F:\。
連結
輸出或設定 PATH 環境變數的值。輸出時,在輸出的開頭包含“PATH=”。
示例
- path
- 輸出 PATH。示例輸出
- PATH=C:\Windows\system32;C:\Windows;C:\Program Files\Python27
- 輸出 PATH。示例輸出
- path C:\Users\Joe Hoe\Scripts;%path%
- 將 C:\Users\Joe Hoe\Scripts 擴充套件到路徑,僅適用於 cmd.exe 程序。
- path ;
- 清空路徑。
- echo %path% | perl -pe "s/;/\n/g" | sort
- 如果安裝了 perl,則顯示路徑中排序的資料夾。
連結
提示使用者並等待輸入一行。
連結
更改驅動器和從目錄堆疊彈出的目錄。目錄堆疊使用PUSHD命令填充。
連結
可用於更改或重置cmd.exe提示符。它設定PROMPT環境變數的值。
C:\>PROMPT MyPrompt$G
MyPrompt>CD
C:\
MyPrompt>PROMPT
C:\>
PROMPT命令用於將提示符設定為“MyPrompt>”。CD顯示當前目錄路徑為“C:\”。不帶任何引數使用PROMPT會將提示符恢復為目錄路徑。
連結
將當前目錄推入目錄堆疊,使其可供POPD命令檢索,並且如果執行時帶有引數,則更改為作為引數指定的目錄。
連結
刪除目錄。另請參見其同義詞RMDIR和反義詞MD。預設情況下,只能刪除空目錄。還可以鍵入“rd /?”。
示例
- rd Dir1
- rd Dir1 Dir2
- rd "My Dir With Spaces"
- rd /s Dir1
- 刪除目錄Dir1,包括其中的所有檔案和子目錄,在繼續刪除之前會先詢問一次是否確認。要遞迴刪除巢狀目錄中的檔案並針對每個檔案進行確認,請使用帶/s開關的DEL。
- rd /q /s Dir1
- 與上面類似,但不詢問是否確認。
連結
重新命名檔案和目錄。
示例
- ren filewithtpyo.txt filewithtypo.txt
- ren *.cxx *.cpp
連結
- ss64.com上的ren
- Microsoft上的ren
- Windows RENAME命令如何解釋萬用字元?,superuser.com
這是REN命令的同義詞。
用於批處理檔案中的註釋,防止執行註釋內容。
一個例子
REM A remark that does not get executed
echo Hello REM This remark gets displayed by echo
echo Hello & REM This remark gets ignored as wished
:: This sentence has been marked as a remark using double colon.
REM通常放置在一行的開頭。如果放置在命令後面,則不起作用,除非前面有與號,如上例所示。
雙冒號是REM的替代方法。當在括號中序列的中間使用時,它可能會導致問題,例如在FOR迴圈中使用的那些。雙冒號似乎只是一個技巧,一個以冒號開頭的標籤。
連結
- ss64.com上的rem
- Microsoft上的rem
- 在批處理檔案中我應該使用哪種註釋樣式?,stackoverflow.com
這是RD的同義詞。
輸出或設定環境變數。使用/P開關,它會提示使用者輸入,並將結果儲存在變數中。使用/A開關,它會執行簡單的算術運算,並將結果儲存在變數中。對於字串賦值,通常避免等號前後有空格,因為它們會導致通常不希望出現的結果:“set name = Peter”將賦值給變數“name ”,而“set name=Peter”將賦值給變數“name”。另請參見#環境變數和#計算。
示例
- set
- 以VAR=VALUE的格式輸出環境變數及其值的列表,每行一個變數。
- set home
- 以VAR=VALUE的格式輸出名稱以“home”開頭的變數的環境變數及其值的列表(不區分大小寫),每行一個變數。
- set HOME
- 如上所述;變數名稱字首和變數名稱之間的匹配不區分大小寫。
- set myname=Joe Hoe
- 將變數設定為新值。
- set mynumber=56
- 將變數設定為“56”的字串值。
- set mynumber=
- 取消設定變數,將其從變數中刪除。等號(=)必須是最後一個字元;如果等號後面有任何空格,它們將成為變數的新值。
- set home=%home%;C:\Program Files\My Bin Folder
- set /P user_input=Enter an integer
- set /P firstline=< File.txt
- 將變數設定為檔案的第一行。其他作業系統的head -1命令的等效項。
- set /A result = 4 * ( 6 / 3 )
- 使用計算結果設定result變數。另請參見#計算。
- set name = Peter
echo *%name %*- 將變數“name ”(末尾帶空格)的值設定為“ Peter”(開頭帶空格)。目的可能是使用“set name=Peter”,不帶分隔空格。
連結
在批處理檔案中使用時,會使對環境變數的所有進一步更改都對當前批處理檔案本地化。在批處理檔案外部使用時,不執行任何操作。可以使用ENDLOCAL結束。退出批處理檔案會自動呼叫“end local”。可用於建立子程式:請參見函式。
此外,還可以使用它來啟用延遲擴充套件,例如:“setlocal EnableDelayedExpansion”。延遲擴充套件包括變數名稱括在感嘆號中,僅在執行到達其使用位置後才替換為其值,而不是在更早的點替換。
以下是在指令碼中使用延遲擴充套件的示例,該指令碼列印檔案的指定數量的第一行,提供其他作業系統中已知的“head”命令的部分功能
@echo off
call :myhead 2 File.txt
exit /b
:: Function myhead
:: ===============
:: %1 - lines count, %2 - file name
:myhead
setlocal EnableDelayedExpansion
set counter=1
for /f "tokens=*" %%i in (%2) do (
echo %%i
set /a counter=!counter!+1
if !counter! gtr %1 exit /b
)
exit /b
連結
將批處理檔案引數沿其移動,但不影響%*。因此,如果%1=Hello 1,%2=Hello 2,%3=Hello 3,則在SHIFT之後,%1=Hello 2,%2=Hello 3,但%*為“Hello 1” “Hello 2” “Hello 3”。
連結
在新視窗中啟動程式或開啟文件。使用一種不清楚的演算法來確定傳遞的第一個引數是視窗標題還是要執行的程式;假設:它使用第一個引數周圍是否存在引號作為提示,表明它是視窗標題。
示例
- start notepad.exe & echo "Done."
- 啟動notepad.exe,繼續執行下一條命令,而無需等待已啟動的命令完成。關鍵詞:非同步。
- start "notepad.exe"
- 啟動一個新的控制檯視窗,notepad.exe作為其標題,顯然是一個不希望的結果。
- start "" "C:\Program Files\Internet Explorer\iexplore.exe"
- 啟動Internet Explorer。作為第一個引數傳遞的空""是實際上未開啟的控制檯的視窗標題,或者至少不是可見的。
- start "C:\Program Files\Internet Explorer\iexplore.exe"
- 啟動一個新的控制檯視窗,"C:\Program Files\Internet Explorer\iexplore.exe"作為其標題,顯然是一個不希望的結果。
- start /wait notepad.exe & echo "Done."
- 啟動notepad.exe,等待其結束後再繼續。
- start /low notepad.exe & echo "Done."
- 如上所述,但以低優先順序啟動程式。
- start "" MyFile.xls
- 在分配開啟它的程式中開啟文件。
- start
- 在相同的當前資料夾中啟動一個新的控制檯(命令列視窗)。
- start .
- 在Windows資源管理器中開啟當前資料夾。
- start ..
- 在Windows資源管理器中開啟父資料夾。
- start "" "mailto:"
- 啟動編寫新電子郵件的應用程式。
- start "" "mailto:joe.hoe@hoemail.com?subject=Notification&body=Hello Joe, I'd like to..."
- 啟動編寫新電子郵件的應用程式,指定新電子郵件的收件人、主題和正文。
- start "" "mailto:joe.hoe@hoemail.com?subject=Notification&body=Hello Joe,%0a%0aI'd like to..."
- 如上所述,使用%0a輸入換行符。
- start /b TODO:example-application-where-this-is-useful
- 啟動應用程式而不開啟新的控制檯視窗,將輸出重定向到呼叫start命令的控制檯。
連結
- ss64.com上的start
- Microsoft上的start
- 如何在Outlook中使用命令列開關建立預先設定地址的電子郵件?,support.microsoft.com
輸出或設定系統時間。另請參見#DATE以及#特殊變數名稱中的TIME變數。
示例
- time /t
- 以HH:MM格式輸出系統時間,不顯示秒和毫秒。例如輸出:09:19。
- time
- 以特定於區域設定的格式輸出系統時間,可能包含秒和百分之一秒,並提示輸入新的時間進行設定;時間前面帶有特定於區域設定的訊息,通常是“當前時間:”的翻譯。因此,輸出格式與“time /t”的輸出格式不同。
- echo %time%
- 使用特殊變數TIME輸出當前時間,以特定於區域設定的格式顯示小時、分鐘、秒,以及可能包含的百分之一秒。例如,在一個區域設定中的輸出:9:19:31.55。
- echo %time% & timeout 1 >nul & echo,|time
- 在中間的命令(此處為timeout 1)前後輸出時間。可用於測量中間序列的執行時間;關鍵詞:需要多長時間。
連結
設定在控制檯視窗中顯示的標題。
連結
將檔案或檔案的內容列印到輸出。
示例
- type filename.txt
- type a.txt b.txt
- type *.txt
- type NUL > tmp.txt
- 建立空檔案(空白檔案)。
連結
顯示命令處理器或作業系統版本。
C:\>VER
Microsoft Windows XP [Version 5.1.2600]
C:\>
一些版本字串
- Microsoft Windows [版本 5.1.2600]
- 適用於Windows XP
- Microsoft Windows [版本 6.0.6000]
- 適用於Windows Vista
- ...
“版本”一詞是本地化的。
連結
- ver 在ss64.com
- ver 在Microsoft
- 作業系統版本在Microsoft
- Microsoft Windows版本列表,wikipedia.org
- Windows 內部版本號,eddiejackson.net
- mxpv/windows_build_numbers.txt,gist.github.com
設定或清除設定,以驗證是否正確寫入COPY檔案等。
連結
輸出卷標。
連結
Windows 命令直譯器可用的外部命令是單獨的可執行程式檔案,由 Microsoft 提供作業系統,或作為第三方命令直譯器的標準捆綁包提供。透過替換程式檔案,可以更改這些命令的含義和功能。
許多(但並非所有)外部命令都支援“/?”約定,這會導致它們將其聯機使用資訊寫入標準輸出,然後以狀態程式碼0退出。
輸出或更改地址解析協議快取中的專案,該快取將 IP 地址對映到物理地址。
連結
計劃在特定時間執行程式。另請參見SCHTASKS。
連結
輸出或設定檔案屬性。在沒有引數的情況下,它將輸出當前目錄中所有檔案的屬性。在沒有屬性修改指令的情況下,它將輸出與給定搜尋萬用字元規範匹配的檔案和目錄的屬性。類似於其他作業系統的chmod。
修改指令
- 要新增屬性,請在其字母前附加“+”。
- 要刪除屬性,請在其字母前附加“-”。
- 屬性
- A - 存檔
- H - 隱藏
- S - 系統
- R - 只讀
- …以及其他一些。
示例
- attrib
- 輸出當前目錄中所有檔案的屬性。
- attrib File.txt
- 輸出檔案的屬性。
- attrib +r File.txt
- 向檔案新增“只讀”屬性。
- attrib -a File.txt
- 從檔案刪除“存檔”屬性。
- attrib -a +r File.txt
- 刪除“存檔”屬性並向檔案新增“只讀”屬性。
- attrib +r *.txt
- 作用於一組檔案。
- attrib /S +r *.txt
- 在子目錄中遞迴地執行操作。
更多資訊,請鍵入“attrib /?”。
連結
(XP中沒有)。編輯啟動配置資料 (BCD) 檔案。更多資訊,請鍵入“bcdedit /?”。
連結
輸出或更改任意訪問控制列表 (DACL)。另請參見ICACLS。更多資訊,請鍵入“cacls /?”。
連結
輸出或設定活動內碼表編號。更多資訊,請鍵入“chcp /?”。
連結
檢查磁碟是否存在磁碟問題,列出它們,並在需要時修復它們。更多資訊,請鍵入“chkdsk /?”。
連結
顯示或設定是否應在計算機啟動時執行系統檢查。系統檢查使用Autochk.exe完成。“NTFS”命令名稱的一部分具有誤導性,因為該命令不僅適用於NTFS檔案系統,也適用於FAT和FAT32檔案系統。更多資訊,請鍵入“chkntfs /?”。
連結
允許使用者透過按單個鍵選擇多個選項之一,並根據所選選項設定錯誤級別。在Windows 2000和Windows XP中不存在,它在Windows Vista中重新引入,並在Windows 7和8中保留。
示例
- choice /m "您同意嗎"
- 向用戶顯示一個是/否問題,對於是,錯誤級別設定為1,對於否,錯誤級別設定為2。如果使用者按下Control + C,則錯誤級別為0。
- choice /c rgb /m "您更喜歡哪種顏色"
- 向用戶顯示一個問題,並指示使用者的字母。響應使用者按下r、g或b,錯誤級別設定為1、2或3。
另一種方法是“set /p”;請參見SET。
連結
顯示加密狀態,加密或解密NTFS捲上的資料夾。
連結
(XP中沒有,或從Server 2003複製)將管道輸入放置到剪貼簿。
示例
- set | clip
- 將環境變數列表放置到剪貼簿。
- clip < File1.txt
- 將File1.txt的內容放置到剪貼簿。
連結
呼叫另一個 Microsoft CMD 例項。
連結
比較檔案。另請參閱 FC。
連結
顯示或更改 NTFS 分割槽上檔案或資料夾的壓縮方式。
連結
將卷從 FAT16 或 FAT32 檔案系統轉換為 NTFS 檔案系統。
連結
允許以互動方式檢查檔案和記憶體內容,以組合語言、十六進位制或 ASCII 格式顯示。適用於 32 位 Windows(包括 Windows 7);在 64 位 Windows 中的可用性尚不清楚。在現代 Windows 中,可作為快速檢視檔案十六進位制內容的工具。關鍵詞:十六進位制轉儲、hexdump、十六進位制轉儲、檢視十六進位制、檢視十六進位制、反彙編程式。
Debug 提供了自己的命令列。在命令列中,鍵入“?”以查詢有關除錯命令的資訊。
要檢視檔案的十六進位制內容,請使用檔名作為引數呼叫 debug.exe,然後在除錯命令列中重複鍵入“d”並按 Enter 鍵。
限制
- 作為 DOS 程式,debug 無法處理長檔名。使用 dir /x 查詢 8.3 檔名,然後對該檔名應用 debug。
- Debug 無法檢視較大的檔案。
連結
- 適用於 Windows XP 的 Debug,來自 TechNet/Microsoft 文件
- 適用於 MS-DOS 的 Debug,來自 TechNet/Microsoft 文件
- W:Debug(命令)
比較兩張軟盤的內容。
連結
將一張軟盤的內容複製到另一張軟盤。
連結
顯示和配置磁碟分割槽的屬性。
連結
最重要的是,建立其他作業系統中稱為別名的宏。此外,還提供與命令歷史記錄和增強型命令列編輯相關的功能。宏是簡短批處理指令碼的替代方案。
與宏相關的示例
- doskey da=dir /s /b
- 建立一個名為“da”的單個宏
- doskey np=notepad $1
- 建立一個將第一個引數傳遞給記事本的單個宏。
- doskey /macrofile=doskeymacros.txt
- 從檔案中載入宏定義。
- doskey /macros
- 列出所有已定義的宏及其定義。
- doskey /macros | find "da"
- 列出所有包含“da”作為子字串的宏定義;另請參閱 FIND。
與命令歷史記錄相關的示例
- doskey /history
- 列出完整的命令歷史記錄。
- doskey /history | find "dir"
- 列出命令歷史記錄中每個包含“dir”作為子字串的行
- doskey /listsize=100
- 將命令歷史記錄的大小設定為 100。
要從命令列獲取 doskey 的幫助,請鍵入“doskey /?”。
連結
顯示所有已安裝的裝置驅動程式及其屬性。
連結
從壓縮的 .cab 壓縮包檔案中提取檔案。另請參閱 #MAKECAB。
連結
比較檔案,以一種特殊的方式顯示其內容的差異。
示例
- fc File1.txt File2.txt >NUL && Echo Same || echo Different or error
- 使用 fc 的錯誤級別檢測差異。錯誤級別為零表示檔案相同;非零可能表示檔案不同,也可能表示其中一個檔案不存在。
連結
搜尋檔案或輸入、輸出中是否存在字串,輸出匹配的行。與 FINDSTR 不同,它不能遞迴搜尋資料夾,不能搜尋正則表示式,需要在搜尋字串周圍加上引號,並且將空格視為字面意義上的空格,而不是邏輯或。
示例
- find "(object" *.txt
- dir /S /B | find "receipt"
- dir /S /B | find /I /V "receipt"
- 列印 dir 命令輸出中所有不匹配的行,忽略字母大小寫。
- find /C "inlined" *.h
- 不輸出匹配的行,而是輸出其計數。如果搜尋多個檔案,則每個檔案前面都有一系列破折號,後面跟著檔名;不輸出所有檔案中匹配行的總數。
- find /C /V "" < file.txt
- 輸出“file.txt”中的行數,也稱為行計數。執行其他作業系統中“wc -l”的功能。透過將“”視為行中找不到的字串來工作。重定向的使用防止檔名在行數之前輸出。
- type file.txt | find /C /V ""
- 與上面類似,但語法不同。
- type *.txt 2>NUL | find /C /V ""
- 輸出當前資料夾中以“.txt”結尾的檔案的行數總和。“2>NUL”是標準錯誤的重定向,它從輸出中刪除了檔名稱後跟空行的內容。
- find "Schönheit" *.txt
- 如果從以 unicode UTF-8 編碼儲存的批處理檔案中執行,則會在 UTF-8 編碼的 *.txt 檔案中搜索搜尋詞“Schönheit”。要使此功能正常工作,批處理檔案不得包含記事本在以 UTF-8 編碼儲存時寫入的位元組順序標記。Notepad++ 是一個可以讓你編寫不帶位元組順序標記的 UTF-8 編碼純文字檔案的程式示例。雖然這對 find 命令有效,但對 #FINDSTR 無效。
- find "Copyright" C:\Windows\system32\a*.exe
- 不僅適用於文字檔案,也適用於二進位制檔案。
連結
在檔案中搜索正則表示式或文字字串。執行其他作業系統中稱為“grep”命令的一些功能,但在其支援的正則表示式方面要有限得多。
除非使用 /c 選項阻止,否則將正則表示式中的空格視為析取,也稱為邏輯或。
示例
- findstr /s "[0-9][0-9].*[0-9][0-9]" *.h *.cpp
- 遞迴搜尋所有以點 h 或點 cpp 結尾的檔案,僅列印包含兩個連續十進位制數字後跟任何內容後跟兩個連續十進位制數字的行。
- findstr "a.*b a.*c" File.txt
- 輸出 File.txt 中所有與兩個由空格分隔的正則表示式中的任何一個匹配的行。因此,其效果是對正則表示式進行邏輯或操作。
- echo world | findstr "hello wo.ld"
- 不匹配。由於空格之前的第一個專案不像是正則表示式,因此 findstr 將整個搜尋詞視為普通搜尋詞。
- echo world | findstr /r "hello wo.ld"
- 匹配。使用 /r 強制進行正則表示式處理。
- findstr /r /c:"ID: *[0-9]*" File.txt
- 輸出 File.txt 中所有與包含空格的單個正則表示式匹配的行。使用 /c 可以防止空格被視為邏輯或。使用 /r 會啟用正則表示式處理,該處理預設情況下會被 /c 停用。要測試這一點,請嘗試以下操作
- echo ID: 12|findstr /r /c:"ID: *[0-9]*$"
- 匹配。
- echo ID: 12|findstr /c:"ID: *[0-9]*$"
- 不匹配,因為搜尋字串未被解釋為正則表示式。
- echo ID: abc|findstr "ID: *[0-9]*$"
- 儘管 echo 的輸出未能與完整的正則表示式匹配,但仍然匹配:搜尋被解釋為搜尋與“ID:”或“*[0-9]*$”匹配的行。
- echo ID: 12|findstr /r /c:"ID: *[0-9]*$"
- 輸出 File.txt 中所有與包含空格的單個正則表示式匹配的行。使用 /c 可以防止空格被視為邏輯或。使用 /r 會啟用正則表示式處理,該處理預設情況下會被 /c 停用。要測試這一點,請嘗試以下操作
- findstr /ric:"id: *[0-9]*" File.txt
- 執行與上一個示例相同的操作,但以不區分大小寫的方式。
- 雖然 findstr 允許在單個“/”後面累積這種開關,但這並不是所有命令都支援的。例如,“dir /bs”不起作用,而“dir /b /s”起作用。
- 要測試這一點,請嘗試以下操作
- echo ID: 12|findstr /ric:"id: *[0-9]*$"
- echo ID: ab|findstr /ric:"id: *[0-9]*$"
- findstr /msric:"id: *[0-9]*" *.txt
- 類似上面,但遞迴搜尋所有檔案(/s),只顯示匹配的檔案,而不是匹配的行(/m)。
- echo hel lo | findstr /c:"hel lo" /c:world
- /c 開關可以多次使用以建立邏輯或。
- echo \hello\ | findstr "\hello\"
- 不匹配。引號和其他多個字元之前的反斜槓充當轉義符;因此,\" 匹配 "。
- echo \hello\ | findstr "\\hello\\"
- 匹配。傳遞給 findstr 的雙反斜槓代表單個反斜槓。
- echo \hello\ | findstr \hello\
- 匹配。傳遞給 findstr 的單個反斜槓都不後跟反斜槓用作轉義符的字元。
- echo ^"hey | findstr \^"hey | more
- 要搜尋引號(雙引號),需要對其進行兩次轉義:一次用於使用插入符號 (^) 的 shell,一次用於使用反斜槓 (\) 的 findstr。
- echo ^"hey | findstr ^"\^"hey there^" | more
- 要搜尋引號並將搜尋詞也括在引號中,需要使用插入符號 (^) 為 shell 轉義封閉引號。
- echo //comment line | findstr \//
- 如果正斜槓 (/) 是搜尋詞中的第一個字元,則需要使用反斜槓 (\) 對其進行轉義。即使搜尋詞括在引號中,也需要轉義。
- findstr /f:FileList.txt def.*()
- 在 FileList.txt 中指定的檔案中搜索,每行一個檔案。FileList.txt 中的檔名可以包含空格,並且不需要用引號括起來才能正常工作。
- findstr /g:SearchTermsFile.txt *.txt
- 搜尋 SearchTermsFile.txt 中找到的搜尋詞,每行一個搜尋詞。空格不用於分隔兩個搜尋詞;相反,每一行都是一個完整的搜尋詞。如果至少有一個搜尋詞匹配,則匹配該行。如果第一個搜尋詞看起來像正則表示式,則搜尋將是正則表示式搜尋,但如果它看起來像普通搜尋詞,則整個搜尋將是普通搜尋,即使第二個或之後的搜尋詞看起來像正則表示式。
- findstr /xlg:File1.txt File2.txt
- 輸出集合交集:兩個檔案中都存在的行。
- findstr /xlvg:File2.txt File1.txt
- 輸出集合差:File1.txt - File2.txt。
- findstr /m Microsoft C:\Windows\system32\*.com
- 不僅適用於文字檔案,也適用於二進位制檔案。
"findstr" 正則表示式的限制,與 "grep" 相比
- 不支援組 -- "\(", "\)"。
- 不支援貪婪迭代器 -- "*?"。
- 不支援“前一個的零個或一個” -- "?"。
- 以及更多。
其他限制:正如在Windows FINDSTR 命令的未公開功能和限制是什麼?中記錄的那樣,存在各種限制和奇怪的行為。
錯誤
- echo bb|findstr "bb baaaa"
- 在多個 Windows 版本中找不到任何內容,但它應該能找到。
還可以考慮鍵入“findstr /?”。
連結
- ss64.com 上的 findstr
- Microsoft 上的 findstr
- Windows FINDSTR 命令的未公開功能和限制是什麼? 在 StackOverflow 上
根據修改日期和檔名模式查詢檔案,並對每個找到的檔案執行命令。非常有限,特別是與其他作業系統的 find 命令相比。自 Windows Vista 起可用。有關更多資訊,請鍵入“forfiles /?”。
示例
- forfiles /s /d 06/10/2015 /c "cmd /c echo @fdate @path"
- 對於當前資料夾及其子資料夾中 2015 年 6 月 10 日或之後修改的每個檔案,輸出檔案修改日期和完整檔案路徑。/d 後面的日期格式是特定於區域設定的。因此,允許查詢最近修改的檔案。關鍵詞:最近更改的檔案。
- forfiles /m *.txt /s /d 06/10/2015 /c "cmd /c echo @fdate @path"
- 如上所述,但僅適用於以 .txt 結尾的檔案。
連結
forfiles /?
格式化磁碟以使用 Windows 支援的檔案系統(如 FAT、FAT32 或 NTFS),從而覆蓋磁碟上的先前內容。謹慎使用。
連結
一個強大的工具,執行與 FAT 和 NTFS 檔案系統相關的操作,理想情況下僅供擁有廣泛作業系統知識的資深使用者使用。
連結
輸出使用者或計算機的組策略設定等。
連結
在圖形模式下啟用擴充套件字元集的顯示。有關更多資訊,請鍵入“graftabl /?”。
連結
顯示命令幫助。
示例
- help
- 顯示 Windows 提供的命令列表。
- help copy
- 顯示 COPY 命令的幫助,也可以透過鍵入“copy /?”來獲得。
連結
(XP 中沒有)顯示或更改檔案或資料夾的自由訪問控制列表 (DACL)。另請參見CACLS。有關更多資訊,請鍵入“icacls /?”。
連結
輸出 Windows IP 配置。按連線顯示配置以及該連線的名稱(即乙太網介面卡本地連線)在其下方顯示與該連線相關的特定資訊,例如 DNS 字尾和 IP 地址以及子網掩碼。
連結
新增、設定或刪除磁碟標籤。
連結
將檔案放入壓縮的 .cab 壓縮包檔案中。另請參見#EXPAND。
連結
一個多用途命令,用於顯示裝置狀態、配置埠和裝置等。
示例
- mode
- 輸出所有裝置(如 com3 和 con)的狀態和配置。
- mode con
- 輸出 con 裝置(命令直譯器正在執行的控制檯)的狀態和配置。
- mode con cols=120 lines=20
- 設定當前控制檯的列數和行數,導致視窗大小調整並清除螢幕。該設定不影響新的控制檯例項。關鍵詞:寬屏、寬視窗、螢幕尺寸、視窗尺寸、調整螢幕大小、調整視窗大小。
- mode 120, 20
- 如上所述:設定列數 (120) 和行數 (20),導致視窗大小調整並清除螢幕。
- mode con cols=120
- 設定當前控制檯的列數,導致視窗大小調整並清除螢幕。它似乎也更改了可見行數,但控制檯緩衝區的總行數似乎沒有改變。
- mode 120
- 如上所述:設定列數。
- mode con cp
- 輸出控制檯的當前內碼表。
- mode con cp select=850
- 設定控制檯的當前內碼表。有關內碼表列表,請參見下面連結的 Microsoft 文件。
- mode con rate=31 delay=1
- 設定按住鍵時字元重複輸入的速率和延遲,控制檯。速率越低,每秒的重複次數越少。
連結
每次顯示一個螢幕的檔案或多個檔案的內容。當重定向到檔案時,也會執行一些轉換,具體取決於使用的開關。
示例
- more Test.txt
- more *.txt
- grep -i sought.*string Source.txt | more /p >Out.txt
- 獲取一個非 Windows grep 命令的輸出,該命令生成的換行符僅由 LF 字元組成,不包含 CR 字元,將 LF 換行符轉換為 CR-LF 換行符。CR-LF 換行符也稱為 DOS 換行符、Windows 換行符、DOS 換行符、Windows 換行符和 CR/LF 行尾,與某些其他作業系統使用的 LF 換行符相反。
- 在某些設定中,如果輸入同時包含 LF 換行符和製表符,則似乎會輸出亂碼。
- 在某些設定中,對於轉換,/p 可能不需要。因此,“more”即使沒有 /p 也會轉換換行符。
- more /t4 Source.txt >Target.txt
- 將製表符轉換為 4 個空格。
- 在某些設定中,即使沒有 /t 開關,製表符轉換也會自動進行。如果是這樣,預設情況下為 8 個空格。
開關 /e
- Windows XP 和 Windows Vista 中“more”的線上文件中未提及該開關。
- 至少在 Windows XP 和 Windows Vista 中,“more /?”中提到了開關 /e。
- 根據“more /?”,該開關應該啟用“more /?”幫助末尾列出的擴充套件功能,例如在按下“=”時顯示當前行。但是,在 Windows XP 和 Windows Vista 中,即使沒有 /e,似乎也預設啟用了該功能。
- 假設:在 Windows XP 和 Windows Vista 中,/e 沒有任何作用;它出於相容性原因而存在。
連結
- more at ss64.com
- more at Microsoft,Windows XP
- more at Microsoft,Windows Server 2008,Windows Vista
提供各種網路服務,具體取決於使用的命令。每個命令可用的變體
- net accounts
- net computer
- net config
- net continue
- net file
- net group
- net help
- net helpmsg
- net localgroup
- net name
- net pause
- net print
- net send
- net session
- net share
- net start
- net statistics
- net stop
- net time
- net use
- net user
- net view
連結
執行與開啟檔案相關的操作,尤其是透過網路由其他使用者開啟的檔案。這些操作包括查詢、顯示和斷開連線。有關更多資訊,請鍵入“openfiles /?”。
連結
語法
- PING /?
- PING address
- PING hostname
透過網路向指定的地址(或指定主機名透過名稱查詢對映到的第一個 IP 地址)傳送ICMP/IP“回顯”資料包,並列印收到的所有響應。
示例
- ping en.wikibooks.org
- ping 91.198.174.192
- ping https://wikibook.tw/
- 不起作用。
連結
從有缺陷磁碟上的損壞檔案中恢復儘可能多的資訊。
連結
查詢或修改 Windows 登錄檔。
第一個引數是以下命令之一:query、add、delete、copy、save、load、unload、restore、compare、export、import 和標誌。要詳細瞭解某個命令,請在其後加上 /?,例如 reg query /?。
連結
用原始檔夾中同名檔案替換目標資料夾中的檔案。
連結
(XP 中沒有)複製檔案和資料夾。另請參見XCOPY和COPY。
示例
- robocopy /s C:\Windows\system C:\Windows-2\system *.dll
- 將以 .dll 結尾的所有檔案從一個目錄複製到另一個目錄,複製巢狀的目錄結構。
連結
執行 DLL 中提供的函式。可用的 DLL 及其函式在不同的 Windows 版本中有所不同。
示例
- rundll32 sysdm.cpl,EditEnvironmentVariables
- 在某些 Windows 版本中,開啟編輯環境變數的對話方塊。
連結
- rundll32 at ss64.com
- 在Microsoft
- rundll at robvanderwoude.com
- dx21.com - 列出 rundll32 示例
控制 Windows 服務,支援啟動、停止、查詢等。Windows 服務類似於程序。Windows 服務要麼在其自己的程序中託管,要麼託管在 svchost.exe 程序的例項中,通常在一個例項中有多個服務。可以使用 Sysinternals 的免費下載的 Process Explorer 找到特定服務的處理器時間使用情況,方法是轉到服務的屬性,然後轉到“執行緒”選項卡。另一個能夠控制服務的命令是NET。TASKLIST可以使用 /svc 開關列出託管的服務。
示例
- sc start wuauserv
- 啟動 wuauserv 服務。
- sc stop wuauserv
- sc query wuauserv
- sc query
- 輸出有關所有服務的資訊。
- sc config SysMain start= disabled
- 確保在啟動後停用 SysMain 服務。SysMain 是 SuperFetch 服務,透過嘗試猜測哪些程式將在載入到 RAM 中以防使用,並載入它們,從而導致重複的硬碟活動。請注意,在 = 之前必須沒有空格,在 = 之後必須有空格。
連結
計劃在特定時間執行程式,比AT更強大。
連結
類似於SET,但影響整個計算機而不是當前控制檯或程序。Windows XP 中不可用;Windows Vista 及更高版本中可用。
連結
- setx at ss64.com
- setx at Microsoft,Windows Server 2008,Windows Vista
關閉計算機或登出當前使用者。
示例
- shutdown /s
- 關閉計算機。
- shutdown /s /t 0
- 立即關閉計算機。
- shutdown /l
- 登出當前使用者。
連結
按字母順序排序,從 A 到 Z 或 Z 到 A,不區分大小寫。無法按數字排序:如果輸入每行包含一個整數,“12”在“9”之前。
示例
- sort File.txt
- 輸出 File.txt 的排序內容。
- sort /r File.txt
- 按反向順序排序,從 Z 到 A。
- dir /b | sort
連結
將驅動器號分配給本地資料夾,輸出當前分配或刪除分配。
示例
- subst p: .
- 將 p: 分配給當前資料夾。
- subst
- 輸出以前使用 subst 建立的所有分配。
- subst /d p
- 刪除 p: 分配。
連結
顯示計算機及其作業系統的配置。
連結
結束一個或多個任務。
示例
- taskkill /im AcroRd32.exe
- 結束所有名為“AcroRd32.exe”的程序;從而結束所有開啟的 Acrobat Reader 例項。可以使用 tasklist 找到名稱。
- taskkill /f /im AcroRd32.exe
- 與上面相同,但強制執行。成功結束了一些沒有 /f 則無法結束的程序。
- tasklist | find "notepad"
taskkill /PID 5792
- 結束程序 ID (PID) 為 5792 的程序;假設您已使用 tasklist 找到了 PID。
連結
列出任務,包括任務名稱和程序 ID (PID)。
示例
- tasklist | sort
- tasklist | find "AcroRd"
- tasklist | find /C "chrome.exe"
- 輸出名為“chrome.exe”的任務數量,屬於 Google Chrome 瀏覽器。
- tasklist /svc | findstr svchost
- 輸出在 svchost.exe 程序中託管的 Windows 服務,以及有關該程序的常規資訊。
連結
等待指定秒數,顯示剩餘秒數,允許使用者透過按任意鍵中斷等待。也稱為延遲或睡眠。在 Windows Vista 及更高版本中可用。
示例
- timeout /t 5
- 等待五秒鐘,允許使用者透過按任意鍵取消等待。
- timeout /t 5 /nobreak
- 等待五秒鐘,忽略除 Control + C 之外的使用者輸入。
- timeout /t 5 /nobreak >nul
- 與上面相同,但沒有輸出。
Windows XP 中的解決方法
- ping -n 6 127.0.0.1 >nul
- 等待五秒鐘;-n 後面的數字是等待的秒數加 1。
Windows XP 中基於 Perl 的解決方法,需要安裝 Perl
- perl -e "sleep 5"
- 等待 5 秒。
連結
- timeout 在 ss64.com 上
- timeout 在 Microsoft 上
- 如何在批處理指令碼中等待? 在 stackoverflow.com 上
- 在批處理檔案中睡眠 在 stackoverflow.com 上
將當前目錄的所有子目錄的樹輸出到任何級別的遞迴或深度。如果與 /F 開關一起使用,則不僅輸出子目錄,還輸出檔案。
示例
- tree
- tree /f
- 除了目錄之外,還包括列表中的檔案。
- tree /f /a
- 與上面相同,但使用 7 位 ASCII 字元(包括“+”、“-”和“\”)繪製樹。
使用 8 位 ASCII 字元的樹片段
├───winevt │ ├───Logs │ └───TraceFormat ├───winrm
使用 7 位 ASCII 字元的樹片段
+---winevt | +---Logs | \---TraceFormat +---winrm
連結
輸出檔案或檔名模式的一個或多個位置,其中檔案或模式不需要宣告副檔名,如果它在 PATHEXT 中列出,例如 .exe。預設情況下在當前目錄和 PATH 中搜索。執行一些其他作業系統的“which”命令的工作,但更靈活。
在 Windows 2003、Windows Vista、Windows 7 及更高版本中可用;在 Windows XP 中不可用。下面示例中提供了可在 Windows XP 中使用的替代方案。
找不到內部命令,因為沒有與之匹配的 .exe 檔案。
示例
- where find
- 輸出 find 命令的位置,可能是“C:\Windows\System32\find.exe”。只要 .exe 副檔名在 PATHEXT 中列出,就不需要指定它,預設情況下它是列出的。
- 如果路徑中有多個 find 命令,則輸出兩個命令的路徑。在某些情況下,它可能會輸出以下內容
C:\Windows\System32\find.exe
C:\Program Files\GnuWin32\bin\find.exe
- for %i in (find.exe) do @echo %~$PATH:i
- 在 Windows XP 上輸出“find.exe”的位置。與 where 命令不同,名稱必須包含“.exe”。
- where /r . Tasks*
- 從當前資料夾遞迴搜尋名稱與“Task*”匹配的檔案。類似於“dir /b /s Tasks*”。/r 開關停用在 PATH 中的資料夾中搜索。
- where *.bat
- 輸出當前目錄和 PATH 中的目錄中的所有 .bat 檔案。因此,輸出所有無需輸入完整路徑即可執行的 .bat 檔案。
- where ls*.bat
- 與上面相同,也限制 .bat 檔名稱的開頭。
- where ls*
- 與上面相同,但對副檔名沒有限制。如果在當前目錄或路徑中,則查詢 lsdisks.bat、lsmice.pl 和 lsmnts.py。
- where *.exe *.com | more
- 輸出路徑和當前資料夾中無數的 .exe 和 .com 檔案,包括 C:\Windows\System32 中的檔案。
- where $path:*.bat
- 輸出路徑中的 .bat 檔案,但不輸出當前資料夾中的檔案,除非當前資料夾在 PATH 中。可以使用包含目錄列表的其他環境變數代替 path。
- where $windir:*.exe
- 輸出在 WINDIR 環境變數中宣告的資料夾中找到的 .exe 檔案。
- where $path:*.bat $windir:*.exe
- 可以進行組合。輸出與兩個查詢中的任一個匹配的所有檔案。
- where /q *.bat && echo Found
- 抑制標準輸出和錯誤輸出,但設定錯誤級別,以便對其進行測試。無論是否使用 /q,都會設定錯誤級別。
連結
啟動 Windows Management Instrumentation 命令列 (WMIC),或者在給出引數的情況下,將引數作為命令傳遞給 WMIC。Windows XP Home 中沒有。有關更多資訊,請鍵入“wmic /?”。
示例
- wmic logicaldisk get caption,description
- 列出在驅動器號下可訪問的驅動器(磁碟),無論是本地硬碟驅動器、CD-ROM 驅動器、可移動快閃記憶體驅動器、網路驅動器還是使用 #SUBST 建立的驅動器。
- wmic logicaldisk get /format:list
- 輸出“logicaldisk”物件的全部屬性,每個屬性佔據一行。
- wmic logicaldisk get /format:csv
- wmic
Control + C- 進入 wmic 然後中斷它。一個副作用是控制檯緩衝區變得非常寬,並且因此螢幕可以透過滑鼠水平調整大小。這是 wmic 設定控制檯列數較高的結果,您可以使用mode con驗證。您可以透過鍵入mode 1500獲得類似的結果。另請參見 #MODE。
- wmic datafile where name="C:\\Windows\\System32\\cmd.exe" get Version /value
- 輸出 cmd.exe 的版本,應該接近 Windows 版本。
- wmic os get TotalVisibleMemorySize
- 輸出總物理記憶體大小。
- wmic os get TotalVirtualMemorySize
- 輸出總虛擬記憶體大小。
- wmic os get /format:list
- 輸出“os”物件的全部屬性,每個屬性佔據一行。
連結
以比 COPY 更高階的方式複製檔案和目錄,在 Windows Vista 及更高版本中已棄用,取而代之的是 ROBOCOPY。鍵入 xcopy /? 以瞭解更多資訊,包括無數選項。
示例
- xcopy C:\Windows\system
- 複製所有檔案,但不復制巢狀資料夾中的檔案,從原始檔夾(“C:\Windows\system”)複製到當前資料夾。
- xcopy /s /i C:\Windows\system C:\Windows-2\system
- 將所有檔案和資料夾複製到任何巢狀深度(透過“/s”),從原始檔夾(“C:\Windows\system”)複製到“C:\Windows-2\system”,如果“Windows-2\system”不存在則建立它(透過“/i”)。
- xcopy /s /i /d:09-01-2014 C:\Windows\system C:\Windows-2\system
- 與上面相同,但僅複製 2014 年 9 月 1 日或之後更改的檔案。請注意,即使您使用的是非美國 Windows 區域設定,也使用了月優先約定。
- xcopy /L /s /i /d:09-01-2014 C:\Windows\system C:\Windows-2\system
- 與上面示例相同,但透過 /L(僅列出、僅輸出、僅顯示)以測試模式執行。因此,它不會執行任何實際複製操作,而只是列出將要複製的內容。
- xcopy /s /i C:\Windows\system\*.dll C:\Windows-2\system
- 與上面示例之一相同,但僅複製以 .dll 結尾的檔案,包括巢狀資料夾中的檔案。
連結
- PowerShell -- 用於編寫 Windows 作業系統指令碼的現代技術
- VBScript 程式設計 -- 一種語法類似於 Visual Basic 的傳統 Windows 指令碼技術
- ss64.com 上的 Windows CMD 命令 -- 根據知識共享署名-非商業性使用-相同方式共享 2.0 英國:英格蘭及威爾士[1]許可,因此與 Wikibooks 使用的 CC-BY-SA 不相容
- microsoft.com 上的 Windows XP - 命令列參考 A-Z
- microsoft.com 上的 Windows Server 2008R2 - 命令列參考
- microsoft.com 上的 Windows Server 2012R2 - 命令列參考
- microsoft.com 上的 Windows Server 2016 - Windows 命令
- FreeDOS HTML 幫助 在 fdos.org -- FreeDOS 命令的超文字幫助系統,編寫於 2003/2004 年,根據 GNU 自由文件許可證 提供
- 批處理檔案分類,rosettacode.org
- Cmd.exe,wikipedia.org
- 批處理檔案,wikipedia.org