【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了)。
在这里插入图片描述

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