美文网首页
批处理基础知识积累

批处理基础知识积累

作者: O无为学长O | 来源:发表于2023-10-15 02:41 被阅读0次

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

    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
        )
    )
    

    相关文章

      网友评论

          本文标题:批处理基础知识积累

          本文链接:https://www.haomeiwen.com/subject/bgbzbdtx.html