批处理基础知识积累

2023-10-15  本文已影响0人  O无为学长O

积累平时编写批处理脚本时用到的知识,不定期更新。

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 (*) 匹配所有文件,包括批处理文件本身,所以如果不想批处理文件被重命名,需要通过判断排除掉,示例代码:

for /R . %%i in (*) do (
    set /a num+=1
    if "%%~nxi" NEQ "%~nx0" (
        ren "%%i" "!num!%%~xi" 2>nul
    )
)
上一篇 下一篇

猜你喜欢

热点阅读