BAT 脚本完全指南:从入门到实战

BAT 脚本完全指南:从入门到实战

什么是 BAT 脚本

BAT(Batch)脚本是 Windows 系统的批处理文件,用于自动化执行一系列命令。

  • 文件扩展名: .bat.cmd
  • 运行环境: Windows 命令提示符(cmd.exe)

快速开始

创建第一个 BAT 脚本

创建文件 hello.bat

@echo off
echo Hello, World!
pause

说明:

  • @echo off - 关闭命令回显(不显示执行的命令)
  • echo - 输出文本
  • pause - 暂停,等待用户按键

运行: 双击 .bat 文件或在命令行执行

基础语法

变量

@echo off

:: 定义变量
set name=John
set age=25

:: 使用变量(注意:%variable%)
echo Name: %name%
echo Age: %age%

:: 修改变量
set age=26
echo New Age: %age%

pause

注释: 使用 ::REM 开头

用户输入

@echo off

:: 简单输入
set /p name=Please enter your name:
echo Hello, %name%!

:: 选择(Y/N)
set /p confirm=Continue? (Y/N):
if /i "%confirm%"=="Y" (
    echo Continuing...
) else (
    echo Exiting...
)

pause

说明:

  • set /p - 提示用户输入
  • /i - 不区分大小写比较

条件判断(if)

@echo off

set value=10

:: 数值比较
if %value% equ 10 (
    echo Value equals 10
)

:: 字符串比较
if "%value%"=="10" (
    echo String equals 10
)

:: 文件存在检查
if exist "test.txt" (
    echo File exists
) else (
    echo File not found
)

:: 目录存在检查
if exist "C:\temp" (
    echo Directory exists
)

:: 否定(not)
if not exist "missing.txt" (
    echo File does not exist
)

pause

比较运算符:

  • equ - 等于(==)
  • neq - 不等于
  • lss - 小于
  • leq - 小于等于
  • gtr - 大于
  • geq - 大于等于

循环(for)

@echo off

:: 遍历文件
for %%f in (*.txt) do (
    echo File: %%f
)

:: 遍历数字 1 到 5
for /l %%i in (1,1,5) do (
    echo Number: %%i
)

:: 遍历目录
for /d %%d in (*) do (
    echo Directory: %%d
)

:: 递归遍历
for /r %%f in (*.log) do (
    echo Found log: %%f
)

:: 读取文件内容
for /f "tokens=*" %%a in (data.txt) do (
    echo Line: %%a
)

:: 解析 CSV 文件
for /f "tokens=1,2,3 delims=," %%a in (data.csv) do (
    echo Column1: %%a, Column2: %%b, Column3: %%c
)

pause

for 循环参数:

  • /l - 迭代数字
  • /d - 迭代目录
  • /r - 递归迭代
  • /f - 读取文件内容

常用命令

文件操作

@echo off

:: 创建目录
mkdir "C:\backup"

:: 删除目录(含文件)
rd /s /q "C:\temp"

:: 复制文件
copy source.txt dest.txt

:: 复制目录
xcopy "C:\source" "C:\backup" /e /i /y

:: 移动/重命名
move old.txt new.txt

:: 删除文件
del "C:\temp\*.tmp"

:: 列出文件
dir /b *.txt

:: 查找文件
where notepad.exe

文本操作

@echo off

:: 创建文件
echo First line > output.txt
echo Second line >> output.txt

:: 读取文件
type output.txt

:: 查找文本
findstr "error" log.txt

:: 替换文本(需要 PowerShell)
powershell -Command "(Get-Content input.txt) -replace 'old', 'new' | Set-Content output.txt"

系统操作

@echo off

:: 显示环境变量
echo %PATH%

:: 设置临时环境变量
set PATH=%PATH%;C:\new\path

:: 永久设置环境变量(需要管理员权限)
setx PATH "%PATH%;C:\new\path"

:: 获取当前日期时间
echo %date% %time%

:: 调用其他程序
notepad.exe

:: 等待
timeout /t 5

:: 切换目录
cd /d C:\Users\%USERNAME%

:: 获取当前目录
cd

:: 显示完整路径
cd /d %~dp0

特殊变量:

  • %~dp0 - 当前脚本所在目录
  • %0 - 脚本名称
  • %1, %2... - 命令行参数

实用案例

案例1:自动备份脚本

@echo off
:: ====================================
:: 自动备份脚本
:: ====================================

set "source=C:\Users\%USERNAME%\Documents"
set "backup=C:\Backup"
set "timestamp=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%"
set "backup_dir=%backup%\%timestamp%"

:: 创建备份目录
if not exist "%backup_dir%" (
    mkdir "%backup_dir%"
    echo Backup directory created: %backup_dir%
)

:: 复制文件
echo Backing up files...
xcopy "%source%" "%backup_dir%" /e /i /y /d

:: 清理旧备份(保留最近 7 天)
forfiles /p "%backup%" /d -7 /c "cmd /c if @isdir==TRUE rd /s /q @path"

echo Backup completed!
pause

案例2:批量重命名文件

@echo off
:: ====================================
:: 批量重命名图片文件
:: ====================================

setlocal enabledelayedexpansion
set count=1

:: 遍历所有 JPG 文件
for %%f in (*.jpg) do (
    set "old_name=%%f"
    set "new_name=image_!count!.jpg"

    if exist "!new_name!" (
        echo Skipping: !new_name! already exists
    ) else (
        ren "!old_name!" "!new_name!"
        echo Renamed: !old_name! -^> !new_name!
    )

    set /a count+=1
)

echo Total files renamed: !count!
pause

注意: setlocal enabledelayedexpansion 启用延迟变量扩展,使用 !variable! 语法

案例3:清理临时文件

@echo off
:: ====================================
:: 清理系统临时文件
:: ====================================

set /p confirm=Clean temp files? (Y/N):
if /i not "%confirm%"=="Y" exit /b

echo Cleaning...

:: 清理用户临时目录
if exist "%TEMP%" (
    del /f /s /q "%TEMP%\*"
    echo Cleaned: %TEMP%
)

:: 清理 Windows 临时目录
if exist "C:\Windows\Temp" (
    del /f /s /q "C:\Windows\Temp\*"
    echo Cleaned: C:\Windows\Temp
)

:: 清理浏览器缓存
for /d %%d in ("%LOCALAPPDATA%\Google\Chrome\User Data\*") do (
    if exist "%%d\Cache" (
        rd /s /q "%%d\Cache"
    )
)

echo Cleanup completed!
pause

案例4:启动多个程序

@echo off
:: ====================================
:: 启动开发环境
:: ====================================

echo Starting development environment...

:: 启动程序(start 让其在后台运行)
start "" "C:\Program Files\Google\Chrome\Application\chrome.exe"
start "" "C:\Program Files\Microsoft VS Code\Code.exe"
start "" "C:\Program Files\Git\git-bash.exe"

:: 等待几秒
timeout /t 3

:: 打开项目目录
explorer "C:\Projects\myproject"

echo All programs started!
timeout /t 2

案例5:日志分析脚本

@echo off
:: ====================================
:: 分析日志文件中的错误
:: ====================================

set "logfile=C:\Logs\app.log"
set "errorfile=errors.txt"

if not exist "%logfile%" (
    echo Log file not found: %logfile%
    pause
    exit /b
)

echo Analyzing log file: %logfile%
echo ----------------------------------------

:: 查找 ERROR 关键字
findstr /i /c:"ERROR" "%logfile%"
if %errorlevel% equ 0 (
    echo Errors found!
    findstr /i "ERROR" "%logfile%" > "%errorfile%"
    echo Saved to: %errorfile%
) else (
    echo No errors found.
)

:: 统计行数
for /f %%c in ('type "%logfile%" ^| find /c /v ""') do (
    echo Total lines: %%c
)

pause

高级技巧

命令行参数

@echo off

:: %0 - 脚本名称
:: %1, %2... - 参数
:: %* - 所有参数

echo Script: %0
echo Arg1: %1
echo Arg2: %2
echo All args: %*

:: 检查参数数量
if "%~1"=="" (
    echo Usage: %~nx0 ^ ^
    exit /b 1
)

:: 获取参数长度
echo Length of arg1: %~z1

:: 获取完整路径
echo Full path: %~f1

:: 获取驱动器
echo Drive: %~d1

:: 获取路径
echo Path: %~p1

pause

参数修饰符:

  • %~1 - 移除引号
  • %~f1 - 完整路径
  • %~d1 - 驱动器号
  • %~p1 - 路径
  • %~n1 - 文件名
  • %~x1 - 扩展名
  • %~z1 - 文件大小

子程序(调用标签)

@echo off

call :sub1
call :sub2

pause
exit /b

:: 子程序 1
:sub1
echo This is subroutine 1
exit /b

:: 子程序 2
:sub2
echo This is subroutine 2
exit /b

错误处理

@echo off

:: 启用命令扩展
setlocal enabledelayedexpansion

:: 执行命令并检查错误
xcopy source.txt dest.txt
if %errorlevel% neq 0 (
    echo Copy failed with error code: %errorlevel%
    exit /b 1
)

:: 使用 || 和 &&(需要启用扩展)
copy file.txt backup.txt && echo Copy successful
del missing.txt || echo File not found

pause

颜色输出

@echo off

:: 设置控制台颜色
color 0A  :: 黑底绿字

:: 更改颜色
echo Normal text
color 0C  :: 黑底红字
echo Error text
color 0B  :: 黑底青色
echo Info text
color 0E  :: 黑底黄字
echo Warning text

:: 恢复默认
color 07

pause

颜色代码:

  • 0=黑, 1=蓝, 2=绿, 3=青, 4=红, 5=紫, 6=黄, 7=白, 8=灰
  • 9=亮蓝, A=亮绿, B=亮青, C=亮红, D=亮紫, E=亮黄, F=亮白

进度条

@echo off
setlocal enabledelayedexpansion

set total=100
for /l %%i in (1,1,%total%) do (
    set /a percent=%%i*100/%total%
    set /a bars=percent/2

    echo ^|!bars!  %%percent%%^|>con

    :: 模拟工作
    timeout /t 1 >nul
)

echo Complete!
pause

调试技巧

1. 查看 echo 状态

:: 关闭命令回显
@echo off

:: 查看当前 echo 状态
echo

:: 临时关闭回显
echo off

:: 临时打开回显
echo on

2. 暂停执行

:: 方法1:pause
pause

:: 方法2:等待指定秒数
timeout /t 5

:: 方法3:无提示等待
timeout /t 3 >nul

3. 调试模式

@echo off
set "DEBUG=1"

if "%DEBUG%"=="1" (
    echo DEBUG MODE ON
    echo Current directory: %cd%
    echo Script path: %~dp0
)

:: 执行命令
echo Running command...

if "%DEBUG%"=="1" (
    echo Command completed
)

pause

最佳实践

  1. 使用 @echo off - 让输出更清晰
  2. 添加注释 - 使用 :: 说明代码逻辑
  3. 错误处理 - 检查 %errorlevel%
  4. 使用引号 - 处理路径中的空格
  5. 测试脚本 - 先在测试环境验证
  6. 备份重要数据 - 操作前先备份
  7. 使用变量 - 提高脚本可维护性
  8. 输出日志 - 记录执行过程

注意事项

  1. 路径分隔符 - Windows 使用 \ 而非 /
  2. 编码问题 - 使用 UTF-8 或 GBK 编码
  3. 权限问题 - 某些操作需要管理员权限
  4. 变量延迟 - 循环中使用 setlocal enabledelayedexpansion
  5. 特殊字符 - 使用 ^ 转义 & | ( ) < >

相关资源

  • PowerShell - 更强大的 Windows 自动化工具
  • VBScript - 老式 Windows 脚本
  • AutoHotkey - 桌面自动化工具
  • Python - 跨平台脚本语言

参考资料

希望这篇教程对你有帮助!有问题欢迎留言讨论。

发表回复

后才能评论