BAT批處理(二):批量刪除指定文件以及相關簡單的語法結構(系統變量errorlevel,變量延遲等)

BAT批處理(二):批量刪除指定文件以及相關簡單的語法結構(系統變量errorlevel,變量延遲等)

前兩天在使用 VSCode 的時候,看到之前那麼多 cpp 編譯產生的 exe 可執行文件,於是心生一個念頭,我要把它們全部刪掉,但是又不想一個個地刪,便想到了利用 bat 腳本批量刪除 exe 文件。於是在蒐集了大量資料後,開始了編寫。
首先就是一條簡單的 del

del F:\Code\C++\*.exe

但是發現只能刪除掉 C++ 那個文件夾根目錄下的 exe 文件,然後發現,在後面加上 /s,表示在當前目錄遞歸刪除指定文件,就是還要進入子目錄尋找文件。

/a 根據百屬性選擇要刪除的文件
/f 強制刪除只讀度文件
/s 從所有子目錄刪除指定文件
/q 安靜模式。刪除全局通配符時,不要求確知

del F:\Code\C++\*.exe /s

運行之後,嘩啦啦,全刪掉了(在其他盤裏測試一下):
在這裏插入圖片描述
本來其實這樣就可以了,把這個批處理腳本放到 C++ 文件夾根目錄就行了,但是如果多次執行的時候,本來已經沒有 exe 文件了,還要執行,就會提示 找不到 G:\test\*.exe,對於強迫症的我當然不能忍受起碼提示一個 exe文件已經刪完啦 之類的。要這樣寫勢必要進行條件判斷,然後,又去找了很多資料。
一開始搜到一個 errorlevel 的系統變量,會判斷你當前這條語句是否執行,如果成功執行該變量的值爲 0, 否則是 1-255 之間的某一個值,這裏的值主要是根據語句未能成功執行的原因(其實就是跟中斷類型差不多)來決定的,一般是 1

@echo off 
if ERRORLEVEL 1 goto fail
if ERRORLEVEL 0 goto success
goto done
:fail
echo exe文件已經沒有啦,別刪啦~
goto done
:success
echo 正在刪除所有煩人的exe文件...
del F:\Code\C++\*.exe /s
:done
echo 執行完成

運行後發現了中文亂碼,於是改一下編碼爲 ANSI在這裏插入圖片描述
然後再次執行,發現不管 exe 文件是否被刪掉,都會執行 success 標號的語句,說明 del 語句都被執行了,只是找不到文件而已。
在這裏插入圖片描述
這種方法不行那就試試其他方法,用 if exist 條件判斷應該可以吧

@echo off 
::if ERRORLEVEL 1 goto fail
::if ERRORLEVEL 0 goto success
if exist F:\Code\C++\*.exe (goto success) else (goto fail)
goto done
:fail
echo exe文件已經沒有啦,別刪啦~
goto done
:success
echo 正在刪除所有煩人的exe文件...
del F:\Code\C++\*.exe /s
:done
echo 執行完成

這裏的 ::是註釋,當然註釋還有其他寫法

1、:: 註釋內容(第一個冒號後也可以跟任何一個非字母數字的字符)
2、rem 註釋內容(不能出現重定向符號和管道符號)
3、echo 註釋內容(不能出現重定向符號和管道符號)〉nul
4、if not exist nul 註釋內容(不能出現重定向符號和管道符號)
5、:註釋內容(註釋文本不能與已有標籤重名)
6、%註釋內容%(可以用作行間註釋,不能出現重定向符號和管道符號)
7、goto 標籤 註釋內容(可以用作說明goto的條件和執行內容)
8、:標籤 註釋內容(可以用作標籤下方段的執行內容

完美執行。
然後在之後的其他測試中,若 C++ 根目錄下沒有 exe 文件,而在其子文件夾下有 exe 文件的話,就出問題了,因爲 if exist 那行語句只是判斷當前文件夾根目錄下是否存在 exe 文件。那該怎麼辦呢?
應該要對 C++ 根目錄進行遞歸查找,便是 for 語句:

@echo off
cls
set PATH=F:\Code\C++\
set FILE=*.exe	
set cnt=0
for /R %PATH% %%s in (%FILE%) do (
	::echo %%s
	set /a cnt=%cnt%+1
)
echo 刪除了%cnt%個文件!
if %cnt% EQU 0 (goto fail) else (goto success)
goto done
:fail
echo exe文件已經沒有啦,別刪啦~
goto done
:success
echo 正在刪除所有煩人的exe文件...
del *.exe /s
echo 刪除了%cnt%個文件!
goto done
:done
echo 執行完成

for 循環後面的 /R 便是對當前文件夾進行遞歸查找,若存在後綴名爲 .exe 文件,便把計數值+1.然後運行,又出錯了。。。
cnt的值始終爲1,這又是爲什麼呢?
又查了許多資料,發現 批處理語法中還有叫什麼 變量延遲 的語法,具體就是 當我們準備執行一條命令的時候,命令解釋器會先將命令讀取,如果命令中有環境變量,那麼就會將變量的值先讀取來出,然後在運行這條命令,如:echo %cnt%,當我們執行這條命令的時候,命令解釋器會先讀出 %cnt% 的值,然後執行echo,得到的結果是屏幕上顯示出 cnt的值。但是,有的時候,我們在執行一條命令的時候,命令解釋器將環境變量的值讀出來以後,我們的環境變量的值發生了改變,這時個再執行命令就是使用的變量改變前的值,這就不是我們想要的結果了。
也就是,當 for 語句執行時,命令解釋器首先把它變成

for /R %s in (*.exe) do (set /a cnt=0+1 )

因此在這個循環裏面 cnt 就全是0了,這裏我們就需要用到 變量延遲 了,設置 setlocal enabledelayedexpansion,然後將需要使用變量延遲的變量兩邊用 ! 表示,即 set /a cnt=!cnt!+1.
關閉變量延遲的話就是 setlocal disabledelayedexpansion.
全部修改完了 bat 程序如下:

@echo off
cls
setlocal enabledelayedexpansion
set PATH=F:\Code\C++\
set FILE=*.exe	
set cnt=0
for /R %PATH% %%s in (%FILE%) do (
	::echo %%s
	set /a cnt=!cnt!+1
)
if %cnt% EQU 0 (goto fail) else (goto success)
goto done
:fail
echo exe文件已經沒有啦,別刪啦~
goto done
:success
echo 正在刪除所有煩人的exe文件...
del %PATH%%FILE% /s
echo 刪除了%cnt%個文件!
goto done
:done
echo 執行完成
endlocal

大功告成!!

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