【Windows批處理】批處理程序在文件及文件夾管理中的應用實例

批量修改文件名

@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來修改文件名

最後刪除變量以免影響系統或其他批處理程序
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
注意:
在批處理程序運行結束後,應該自動刪除批處理程序中所有自定義的環境 變量,以免影響其他批處理程序。若批處理程序中要用到多個環境變量, 建議使用setlocalendlocal 命令,這樣就無需手動清除自定義的環 境變量

創建編號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了)。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章