文章目錄
批量修改文件名
@echo off
echo 開始更改文件名...
set extension=.rar
set /a sum=0
for %%m in (*) do (
if not "%%m"=="test.bat" (
ren %%m %%m%extension%
set /a sum=sum+1
)
)
echo 文件改名完畢,共%sum%個文件被改名
set sum=
set extension=
將test.bat和要改名的文件放在同一個文件夾中,在當前文件夾中執行cmd
/a
不能省略,表示 sum 是數值類型變量
ren
來修改文件名
最後刪除變量以免影響系統或其他批處理程序
注意:
在批處理程序運行結束後,應該自動刪除批處理程序中所有自定義的環境 變量,以免影響其他批處理程序。若批處理程序中要用到多個環境變量, 建議使用setlocal
和endlocal
命令,這樣就無需手動清除自定義的環 境變量
創建編號0-99的文件
@echo off
echo 正在創建lyric0.txt-lyric99.txt共100個文件...
echo.
echo.
for /l %%n in (0,1,99) do (
echo 最新歌詞集錦 >> lyric%%n.txt
)
echo 文件創建完畢
每個文件內容爲
對代碼進行解釋
for 循環中 /l
參數表示 for 語句在指定的數值範圍循環,該範圍由in
後括號內的值決定。括號中有3個用逗號分隔的數字,第1個數字代表循環 起始值,第2個數字代表步長,第3個數字代表循環終止值
自動循環某個程序
有時需要不斷地運行某個程序,直到達到預期目的。例如,需要不斷地測試局域網內的 某臺機器是否能夠ping通,這時就需要不斷重複運行“ping”命令,直到可正常ping 通爲止
@echo off
echo 正在測試是否可以 ping 通主機 192.168.1.115...
:again
ping 192.168.1.115 > nul
if not %errorlevel% EQU 0 goto again
start "可正常與主機通訊" echo 現在可以正常 ping 通主機 192.168.1.115
利用“ping”命令對“192.168.1.115" 主機進行ping 測試,命令中的“> nul"表 示將“ping”命令的輸出信息發送到空設備而不顯示在屏幕上,從而保證命令行窗口的整潔
正常ping通指定主機返回後,“ping” 命令會設置環境變量"errorlevel"的值爲“0”,ping失敗後則會設置“errorlevel”爲非零值。因此,當 ping 不通時,會執行“goto again”語句,繼續執行ping操作,直到用戶強制終止(ctrl+c)或ping通時
當ping通時,將通過 start
彈出一一個標題爲“可正常與主機通訊”的命令行窗口
下面分別是 ping 不通 和 ping 通的執行結果
顯示批處理完整路徑
@echo off
echo 當前運行的%0文件的完整路徑爲:
echo %~dp0
echo.
~
爲擴展符號,它和不同字母結合所代表的含義不同。%0
代表批處理文件名本身,而%~dp0
則表示了%0
文件的路徑信息。~dp
組合代表將指定的變量擴展到路徑
將文件名自動更名爲系統日期
@echo off
if not exist %1 ( echo 命令用法如下:
echo %0 filename
echo filename:表示需要修改的文件名
echo.
goto end
)
set extension=%~x1
for /F "tokens=1-3 delims=/- " %%A in ('date/t') do set date=%%A%%B%%C
ren %1 %date%%extension%
echo.
echo 文件%1 文件被成功更名爲%date%%extension%
set extension=
set date=
:end
判斷是否存在“%1”文件(%1爲命令行傳給批處理要改名的文件),若文件不存在則執行 if 語句塊,if 語句塊主要顯示了批處理的使用方法,%0 代表當前批處理文件本身文件名。所以如果直接執行 test.bat 而不傳文件名時,運行結果如下:
set extension=%~x1
定義一個變量“extension”,其值爲被修改文件的擴展名。“%1”表示被修改的文件名,也就是我們傳的參數。%~x1
表示“%1”文件的擴展名,“~x"組合表示取變量的擴展名
for循環中,如果批處理文件中直接執行date/t
,會得到今天的時間:
語句的 /f
參數表示使用文件解析過程處理命令輸出、字符串和文件內容,tokens
用於定義“for” 中的變量個數,delims
用於定義字符串的分格符 “/”、“-” 和 空格
for語句根據tokens=1-3 delims=/-
參數指示,將“2020/06/19 週五”字符串分隔爲“2020”、“06”、“19”及“週五”,並將前3個字符串依次賦給“%A”、“%B"、“%%C" 3個for變量
for執行完 date 的值變爲了 20200619,之後使用 ren
來修改 a.txt 的名稱
使用批處理命令自動接收用戶輸入信息
批處理程序在執行過程中有時需要用戶做出選擇,從而決定批處理程序要完成的功能,這就需要批處理程序能夠接收用戶的輸入信息
@echo off
:repeate
cls
echo.
echo.
echo ##########請選擇要執行的操作##########
echo ------1、輸入數字1並按回車,顯示當前日期------
echo ------2、輸入數字2並按回車,顯示當前時間------
echo ------3、輸入數字3並按回車,顯示文件列表------
echo ------4、輸入數字4並按回車,終止批處理操作------
echo.
echo.
echo 請選擇要執行的操作:
set /p num=
if "%num%"=="1" (
cls
echo.
echo.
echo 當前日期爲:
date/t
pause
goto repeate
)
if "%num%"=="2" (
cls
echo.
echo.
echo 當前時間爲:
time/T
pause
goto repeate
)
if "%num%"=="3" (
cls
echo.
echo.
echo 當前目錄下內容爲:
dir /w
pause
goto repeate
)
echo.
echo.
echo 你輸入了%num%字符,批處理自動退出
cls
爲清空屏幕信息
set /p num=
中,我們知道 set用於設置一個變量,/p 允許將變量數值設成用戶輸入的一行輸入,所以這一行命令的意思是:接收用戶輸入的信息,並將用戶輸入的信息以字符串的形式保存在“num”變量中
date/t
在上一個命令中我們用過,“date”命令用於顯示當前系統日期,“/t” 參數表示只顯示日期而不要求用戶輸入新的日期,如果在一個批處理文件中,只執行date
:
"time”命令用於顯示當前系統時間,“/t”參數表示只顯示時間而不要求用戶 輸入新的時間
運行結果如下:
計算當前目錄和子目錄所佔硬盤空間
@echo off
echo.
echo 正在統計目錄所佔空間...
echo ----------------------------
for /f "tokens=*" %%a in ('dir') do (
echo "%%a" | find "個文件" > nul && for /f "tokens=3*" %%b in ("%%a") do (
echo 當前目錄大小:%%b%%c
)
)
echo ----------------------------
echo 子目錄所佔空間大小分別如下:
for /f %%a in ('dir/ad/s/b') do (
for /f "tokens=*" %%b in ('dir %%a\') do (
echo "%%b" | find "個文件" > nul && for /f "tokens=3*" %%c in ("%%b") do (
echo %%a:%%c%%d
)
)
)
第一個 for 循環用於分析 “dir" 命令所顯示的字符串,“/f" 參數表示 for 語句以解 析方式工作,for /f
用來解析文本,讀取字符串。如果不使用參數 “/f”,運行結果只顯示括號裏的文字字符
‘dir’
for 語句首先執行括號中 “dir" 命令。tokens=*
的作用是用來分析文本文件中的內容的,“tokens” 參數只有一個 “*”,表示 “%%a” 將依次代表“dir" 命令輸出的每一行。for 語句的循環次數等於 “dir” 命令顯示結果的行數
“&&"符號連接兩個命令時,表示只有當符號前的命令執行成功後,纔會執行符號後的命令
我的目錄是
如果單獨執行 dir
命令
echo "%%a" | find "個文件" > nul
中 “%%a”是代表 “dir" 命令輸出結果中的一行,“echo “%%a” 命令執行的結果 通過管道符 “I” 送給find
命令,以便查找需要的字符。find "個文件
表示在 %%a 中查找 個文件
字符串,因爲 “dir” 命令顯示的結果中包含 個文件
字符串的行中同時含有當前目錄所佔大 小。>nul
表示將查找結果發送的空設備而不是顯示在命令行
當 &&
符號前的命令執行成功,批處理會繼續執行 &&
後的 for 語句。該 for 語句是對%%a
內容進行詳細的解析, 從而提取出目錄大小信息。此時的%%a
代表 ‘dir’ 命令中包含目錄大小信息的那一行,形如上圖的 “XX 個文件 YY 字節”, “XX"及“YY"都代表具體的數字,“YY”就是 目錄大小
爲了得到 “YY", for 語句對 “%%a” 進行了解析。for語句沒有明確使用 “delims" 參數,即表示使用空格作爲默認的分格符,tokens=3*
表示 “%%b” 代表“%%a”中第3個 被分隔的字符串(表如“YY"),即目錄的大小。“*” 表示第3個字符串後的所有字符串都用一個變量來代替,%%b
代表目錄大小,%%c
代表從%%a
解析出 的"字節" 二字
dir/ad/s/b
表示以最簡潔的方式顯示當前目錄下 所有目錄及子目錄,顯示的結果中每個代表一個目錄(包括完整的路徑名),如果單獨執行 dir/ad/sb
命令
dir %%a\
用於顯示每個子文件夾的內容從而獲得目錄大小。%%a\
代表當前目錄下的子文件夾,tokens
的值設置爲 “*”,表示%%b
依次代表dir %%a\
執行結果中的每一行。 For語句的執行次數等於dir%%a\
執行結果的行數
執行結果如下:
刪除當前目錄及子目錄中的空文件夾
@echo off
echo.
echo 正在刪除當前目錄及子目錄中所有空文件夾,請稍後...
echo ---------------------------------------------------
cd. > listnull.txt
for /f "delims=" %%i in ('dir /ad /b /s') do (
dir /b "%%i" | findstr .>nul || echo %%i>>listnull.txt
)
set /a sum=0
for /f %%i in (listnull.txt) do (
echo "成功刪除空目錄:%%i"
rd /q %%i
set /a sum=sum+1
)
echo ---------------------------------------------------
echo 共成功刪除%cd%目錄及其子目錄下%sum%個空文件夾
echo.
set sum=
del /q listnull.txt > nul
“cd." 命令不顯示任何內容,因此將該命令的結果利用“>”重定向操作符輸出到文件,創建一個空文件。所以這個命令創建了一個名爲"Iistnull.xt" 的空文件,該文件用於存放空目錄列表
dir /ad /b /s
表示顯示當前目錄及所有子目錄中的文件夾,顯示結果中每個文件夾佔一行,for 語句對dir /ad /b /s
命令執行結果進行解析,delims=
表示不使用分隔符,即%%i
依次代表輸出結果中的每一行
||
連接兩個命令時,僅當符號前面的命令執行失敗後,才繼續執行符號後的命令。dir /b "%%i"
命令顯示%%i
目錄中的內容,/b
參數確保%%i
爲空目錄時 不顯示任何內容。dir /b "%%i"
命令執行結果通過管道符|
送給findstr .>nul
命令進 行查找,findstr 的作用是在文件中尋找字符串,.
在findstr
中代表任意符,>nul
將查找結果重定向到空設備
當findstr
命令執行失敗時,表示目錄爲空目錄,批處理會接着執行 “I” 符號後 的命令。echo %%i >>listnull.txt
表示將空目錄存放到“listnull.txt"文件中,以便後面的命令進行刪除
定義一個“sum"數值變量並將其初始值設置爲 0, 該變量用於統計一共刪除多少個空目錄
for 語句對“listnull.txt" 文件中的每一行進行解析
rd /q %%i
命令用於刪除指定的目錄,“/q"用 於刪除目錄時不顯示確認信息
顯示一共刪除的空目錄數,%cd%
代表當前目錄,%sum%
代表刪除的空目錄數
最後用 del
刪除 listnull.txt,使用 /q 表示刪除時不要求確認
執行結果
不同盤符路徑切換
命令行狀態下用戶輸入盤符和冒號,然後按回車即可切換到指定的盤符。但在批處理中 卻不可以使用這種方式,需要通過特殊的命令來完成該操作
@echo off
echo.
echo 從當前盤符切換到 d:\Android 目錄下...
pushd d:\Android
echo d:\Android 目錄中包含以下文件夾:
dir/ad /b
echo.
echo 返回到批處理運行時所在的盤符及路徑
popd
將當前路徑直接切換到 “d:\Android” 路徑下,“pushd” 命令後的參數用於指定要切換的路徑
“dir" 命令的 “/ad” 表示只顯示文件夾,"/b" 表示以簡潔方式顯示文件夾(即不顯示標題信息與摘要)
“popd” 命令返回到最近一次執行 "pushd"命令之間的路徑,爲了避免批處理執行完成後更改當前工作路徑,“popd” 與 “pushd” 通常是成對使用
替換指定文本中字符
echo.
setlocal enabledelayedexpansion
cd. > file_new.txt
echo 正在替換文件中字符...
echo.
for /f %%a in (file.txt) do (
set str=%%a
set str=!str:aaa=bbb!
echo !str!>>file_new.txt
)
ren file.txt file_old.txt
ren file_new.txt file.txt
echo 成功替換文件中指定的字符串,file_old.txt 文件爲修改前的file.txt
set str=
setlocal enabledelayedexpansion
意思是設置本地爲延遲擴展,也就是:延遲變量(想了解延遲變量,看本文最後)
利用cd.
命令建立一個名爲 “file_new.txt" 的空文件,該文件用於存放替換過指定字符串的文件,作爲一個臨時文件
for 語句對 “file.txt” 文件進行解析,"%%a" 依次代表文件中的每一行,for循 環的次數等於"file.xt"文件的行數。“file.txt" 是需要替換某些字符的文件
定義 “str” 變量並賦值爲 “%%a”,即"str" 變量代表 "file.txt"文件中具體某一行
“str=!str:aaa=bbb!” 表示先將 “str” 變量中的 “aaa"替換成"bbb”(將右邊的值"bbb"賦值給"aaa")然後再將替換過的"str"賦值給原先的"str" 變量。兩個!
號之間的"str"使用的變量延時。以冒號(:)作爲操作的開始符
echo !str!>>file_new.txt
將替換過的“str” 存放到"file_ new.txt","!str!" 對"str" 使用了變量延時
然後就是重命名
可以發現多了個 file_old.txt,內容是file.txt替換前的內容。file.txt 內容已經被替換
在文本文件前插入指定內容
@echo off
if "%1"=="" (
echo 命令用法:%0 filename
echo filename表示要插入內容的文件
echo.
echo 未指定要插入內容的文件,無法執行插入操作
echo.
goto end
)
if not exist %1 (
echo.
echo 指定要插入內容的文件%1不存在,請仔細檢查
goto end
)
echo 正在進行插入操作...
echo.
cd. > content.temp
echo %date% >> content.temp
echo %time% >> content.temp
copy content.temp+%1 temp > nul
del /f /q %1 >nul
del /f /q content.temp >nul
ren temp %1
echo 成功在%1文件前插入了當前日期及時間
:end
copy content.temp+%1 temp > nul
中,copy 作用是複製文件,使用方法很簡單:copy 源文件 目的路徑
,其中+
是COPY命令文件連接符, 表示很多文件合併成一個文件, 將"content.temp"與"%1"中的內容按順序放在一起,然後存入"temp"文 件。在"temp"文件,首先是“content.temp" 中的內容,接着是"%1"文件的內容
刪除原先的"%1"文件和使用的臨時存放插入內容的"content.temp"文件,"/f"表示強制方式刪除,"/q"表示刪除時不顯示確認信息
將"temp"文件更名爲原先的"%1",此時的"%1"即是已經在開始插入指 定內容的文件了
運行一下。現在有 file.txt
瞭解延遲變量
瞭解以下延遲變量,爲了更好的說明問題,我們先引入一個例子
@echo off
set a=4
set a=5&echo %a%
pause
先給變量 a 賦值 4,然後用 & 順序執行多條命令(給 a 賦值 5,然後輸出 a),而不管命令是否執行成功。運行程序
爲什麼是4不是5呢?明明已經賦值5了。讓我們先了解一下批處理運行命令的機制:批處理讀取命令時是按行讀取的(另外例如for命令等,其後用一對圓括號閉合的所有語句也當作一行),在處理之前要完成必要的預處理工作,這其中就包括對該行命令中的變量賦值
批處理在運行到這句set a=5&echo %a%
之前,先把這一句整句讀取並做了預處理——對變量a賦了值,那麼 %a% 當然就是4了(沒有爲什麼,批處理就是這樣做的)
而爲了能夠感知環境變量的動態變化,批處理設計了變量延遲。簡單來說,在讀取了一條完整的語句之後,不立即對該行的變量賦值,而會在某個單條語句執行之前再進行賦值,也就是
說"延遲"了對變量的賦值
變量延遲的啓動語句是setlocal enabledelayedexpansion
,並且變量要用一對歎號!!
括起來(注意要用英文的歎號)
@echo off
setlocal enabledelayedexpansion
set a=4
set a=5&echo !a!
pause
開啓變量延遲後,先給變量a賦值爲4,“set a=5&echo !a!”這句是給變量a賦值爲5並輸出(由於啓動了變量延遲,所以批處理能夠感知到動態變化,即不是先給該行變量賦值,而是在運行過程中給變量賦值,因此此時a的值就是5了)。