批处理基础知识积累
积累平时编写批处理脚本时用到的知识,不定期更新。
1,常用符号
符号 | 含义 |
---|---|
@ | 隐藏命令回显,即命令的执行结果不会再输出到终端显示。 |
% | 引用变量。 %num% 引用普通变量 num ,%i 引用参数变量 i 。 |
: | 标签标记,如 :start 表示start 标签,可以使用goto start 跳转到start 标签执行。 |
:: | 注释符号,表示当前行为注释。 |
> | 将符号左边的内容添加到右边的文件中,会覆盖文件中的已有内容。如:echo hello>123.txt 表示将hello 添加到 123.txt 文件中,如果123.txt 里有内容,会先清除内容,然后添加hello 。 |
>> | 与> 作用相同,但不会覆盖文件中的已有内容,会将新内容添加到原内容后面。 |
| | 将符号左边的执行结果作为参数传递给右边使用,如echo 12345 | findstr '3' 将 echo 12345 的输出结果 12345 传递给 findstr 。 |
^ | 转义字符,可以取消特殊字符的特殊含义,当作普通字符使用。如 echo > 会报错,echo ^> 则会输出符号 > 。 |
() | 语句块,当if , for 之类的语句需要执行多条语句时,使用 () 将语句包裹起来。 |
&& | 如果前面的命令成功执行,则继续执行右边的语句。 |
|| | 如果前面的命令没有成功执行,则执行右边的语句。 |
2,运算符
符号 | 含义 |
---|---|
+ | 加法运算,+= 表示累加运算。 |
- | 减法运算,+= 表示累减运算。 |
* | 乘法运算,+= 表示累乘运算。 |
/ | 除法运算,+= 表示累除运算。 |
% | 取余运算,+= 表示累余运算。 |
EQU |
equal ,关系判断,等于。 |
NEQ |
not equal ,关系判断,不等于。 |
LSS |
less than ,关系判断,小于。 |
LEQ |
less than or equal ,关系判断,小于或等于。 |
GTR |
greater than ,关系判断,大于。 |
GEQ |
greater than or equal ,关系判断,大于或等于。 |
AND | 逻辑与判断,前后两个执行结果都为真,结果为真。 |
OR | 逻辑或判断,前后两个执行结果只要有一个为真,结果为真。 |
NOT | 逻辑否判断,对右边的结果作相反判断,如 if NOT 3 == 1 echo 123 。 |
3,常用命令
setlocal enabledelayedexpansion
启用延迟变量扩展,有时正常声明的变量来不及被使用,比如在循环语句中声明的变量,正常引用变量(如 %name%
),输出的可能不是期望的结果。使用此命令可以得到正确的值,延迟使用的变量使用 !
来引用(如 !num!
),该命令要提前声明,在声明此命令之前无法使用!
引用延迟变量,使用 disabledelayedexpansion
替换 enabledelayedexpansion
可以禁用延迟变量扩展。
echo off
关闭当前命令后面所有命令的屏幕显示,即所有命令的执行结果不再输出到终端显示,使用 @echo off
可以隐藏命令本身的结果输出。
echo on
开启当前命令后面所有命令的屏幕显示,即所有命令的执行结果都会输出到终端显示。
4,批处理文件自身路径处理
命令 | 含义 |
---|---|
%0 | 获取批处理自身的完整路径 |
%~0 | 获取批处理自身的完整路径,并去掉首尾的引号 |
%~nx0 | 获取批处理自身的文件名及后缀名 |
%~n0 | 获取批处理自身的文件名 |
%~x0 | 获取批处理自身的后缀名 |
%~dp0 | 获取批处理自身的完整路径,不含文件名(相当于 %cd%) |
%~d0 | 获取批处理自身的盘符 |
%~z0 | 获取批处理自身的大小 |
%~t0 | 获取批处理自身的修改时间 |
删除自身: del %0
。
扩展知识
cmd /v:on
在命令提示符中启用延迟变量扩展。
cmd /v:off
在命令提示符中禁用延迟变量扩展。
脚本收集
1.将当前文件夹中的所有txt文件按顺序重命名为数字名称
:: 将当前目录中的文件按数字顺序重命名
@echo off
setlocal enabledelayedexpansion
mode con cols=50 lines=9
color a
goto start
:end
exit
:run
cls
set input=0
set num=0
for %%i in (*.txt) do (
set /a num+=1
ren "%%i" "!num!%%~xi" 2>nul
)
echo.&echo.&echo.
echo 除名字有冲突的文件未修改之外 & echo.
echo 所有文件都已重命名,按任意键退出!
pause >nul
goto end
:start
cls
echo.&echo.
echo 请在明确知道脚本用途的情况下使用!
echo.
echo 确定执行脚本请输入 ok ,然后回车
echo.
set /p input= ┤
if "%input%" == "ok" goto run
cls
echo.&echo.&echo.
echo 输入不正确,按任意键退出!
pause >nul
goto end
以上脚本代码在修改为纯数字文件名时不会有问题,但如果名字前面有非数字前缀,则第一个文件会被重复修改两次,比如:
将 a.txt
b.txt
c.txt
改为 1.txt
2.txt
3.txt
不会有问题,但要改为 s1.txt
s2.txt
s3.txt
(s可以为任意字符),则最终结果是 s2.txt
s3.txt
s4.txt
,目前没搞明白是因为什么原因导致的,可以通过将重命名命令单独输出到一个新的批处理文件,然后使用 call
命令调用这个批处理来解决问题:
:: 将当前目录中的文件按数字顺序重命名
@echo off
setlocal enabledelayedexpansion
mode con cols=50 lines=9
color a
goto start
:end
exit
:run
cls
set input=0
set num=0
:: 设置一个不会重复的随机变量名
set tmpname=%DATE%-%TIME%-%RANDOM%
set tmpname=!tmpname::=!
set tmpname=!tmpname:.=!
set tmpname=!tmpname: =!
for %%i in (*.txt) do (
set /a num+=1
echo ren "%%i" "c!num!%%~xi" 2^>nul >>!tmpname!.bat
)
echo.&echo.&echo.
call !tmpname!.bat || echo 除名字有冲突的文件未修改之外 & echo.
echo 所有文件都已重命名,按任意键退出!
del !tmpname!.bat
pause >nul
goto end
:start
cls
echo.&echo.
echo 请在明确知道脚本用途的情况下使用!
echo.
echo 确定执行脚本请输入 ok ,然后回车
echo.
set /p input= ┤
if "%input%" == "ok" goto run
cls
echo.&echo.&echo.
echo 输入不正确,按任意键退出!
pause >nul
goto end
上面代码的核心是 for
语句,并且上面代码只会修改当前目录中的txt文件,如果要修改当前目录和所有子目录,可以通过 /R . (. 表示当前目录)
参数实现:
for /R . %%i in (*.txt) do (
set /a num+=1
echo ren "%%i" "c!num!%%~xi" 2^>nul >>!tmpname!.bat
)
in
关键字后面的小括号为匹配的文件名,可以使用通配符。比如:
-
in (1.txt)
匹配所有的1.txt
文件 -
in (a*.txt)
匹配所有a
开头的txt文件 -
in (*a.txt)
匹配所有a
结尾的文件
in (*)
匹配所有文件,包括批处理文件本身,所以如果不想批处理文件被重命名,需要通过判断排除掉,示例代码:
for /R . %%i in (*) do (
set /a num+=1
if "%%~nxi" NEQ "%~nx0" (
ren "%%i" "!num!%%~xi" 2>nul
)
)