欢迎访问我的博客首页。
Windows 批处理
1. 简单命令
1.1 注释与打印
rem 这是一行注释。
rem 【@echo off】后面的命令不被打印,相对应的是【@echo on】。
@echo off
rem 打印空行,注意中间没有空格。
echo.
pause
1.2 解析命令行
解析命令行参数,已经获取与脚本相关的路径。
@echo off
rem 假设命令是:example.bat parameter1 "parameter 2"
echo %0 %脚本名字:example.bat%
echo %1 %第 1 个参数:parameter1%
echo %2 %第 2 个参数:"parameter 2"%
echo %~2 %第 2 个参数(如果有双引号则去掉):parameter 2%
echo %cd% %执行路径(打开终端的路径)%
echo %~d0 %盘符:D:%
echo %~f0 %路径:D:\bat\example.bat%
echo %~n0 %不含扩展名的文件名:example%
echo %~p0 %所在文件夹路径(不含盘符):\bat\%
echo %~s0 %短路径:D:\bat\example.bat%
echo %~t0 %修改日期:2023/06/29 下午 04:10%
echo %~x0 %扩展名:.bat%
echo %~z0 %字节大小:1006%
echo %~dp0 %所在文件夹路径:D:\bat\%
echo %~sdp0 %所在文件夹短路径:D:\bat\%
1.3 使用变量
为变量赋值使用 set 命令。引用命令行参数使用【%数字】,引用循环遍历使用【%%循环变量】,引用普通变量使用【%普通变量%】。
2. 循环控制
for 循环的语法如下,其中参数可以是空、/r、/d、/l、/f 五者之一。
for 参数 %%循环变量名 in (集合) do (执行语句)
2.1 遍历与递增
现在介绍参数空、/r、/d、/l 的用法,/f 见文件操作。
rem 逐个输出集合元素。
for %%i in (1, a, bc, d2) do (
echo %%i
)
rem 不递归地搜索文件。
for %%i in (D:\example\*.bat) do (
echo %%i
)
rem 递归地搜索所有文件。
for /r %%i in (*) do (
echo %%i
)
rem 不递归地搜索文件夹。
for /d %%i in (D:\example\*) do (
echo %%i
)
rem 输出首项为 1,公差为 5,最大项不超过 20 的等差数列。
for /l %%i in (1, 5, 20) do (
echo %%i
)
2.2 判断与中止
bash 有 if 关键字,没有 break 关键字,可以利用 goto 关键字实现 break 功能。
for /l %%i in (1, 2, 10) do (
echo %%i
if %%i gtr 4 (
goto :next
)
)
:next
条件判断有四种情况,具体情况和代码如下:
- 判断驱动器、文件或文件夹是否存在,使用 if exist 语句。
- 判断字符串是否相等,用 == 运算符。
- 判断数值是否相等,用 equ 关键字。
- 判断变量是否被赋值,用 defined 关键字。
if exist d:\test.txt (
echo yes
) else (
echo no
)
if "abc"=="xyz" (echo yes) else (echo no)
if 1 equ 2 (echo yes) else (echo no)
if defined str (echo yes) else (echo no)
注意 else 不能在一行的开头。数值比较的 6 种关键字分别是:
小于 | 小于等于 | 等于 | 大于等于 | 大于 | 不等于 |
---|---|---|---|---|---|
lss | leq | equ | geq | gtr | neq |
3. 字符串操作
3.1 字符串截取
rem 从目标字符串的指定下标处选取指定长度的字符作为子串,如果不指定长度则截取到最后。
rem set 目标字符串=%源字符串:~起始下标:截取长度%
set str1=abcedfgh
set str2=%str1:~3%
set str3=%str1:~1,4%
echo %str2%
echo %str3%
3.2 字符替换
set str=abcdefghijkl
set str=%str:c=-%
set str=%str:f=mm%
set str=%str:ij=z%
echo %str%
3.3 字符串遍历
字符串遍历可以用于路径分割等,是经常需要的操作。我们使用 while 循环和字符串截取方法遍历字符串。因为 bash 没有 while 关键字,所以我们使用 goto 关键字实现 while 关键字的功能。
set str=abcdef
rem 正序遍历
set str_copy=%str%
:loop
echo %str_copy:~0,1%
if %str_copy%==%str:~-1,1% goto :next
set str_copy=%str_copy:~1%
goto loop
:next
rem 逆序遍历
set str_copy=%str%
:loop
echo %str_copy:~-1,1%
if %str_copy%==%str:~0,1% goto :next
set str_copy=%str_copy:~0,-1%
goto loop
:next
4. 文件操作
4.1 文件查找
dir 命令的使用格式是:dir 参数 路径(可以带通配符),多个参数可以用空格分开也可以不分开。下面的命令使用了 /s 参数,会在 %source_dir% 中递归地搜索 txt 文件。
rem dir 命令
dir /b/s/aa %source_dir%\*.txt
rem /b 不显示标题和摘要
rem /s 递归
rem /a 显示文件和文件夹
rem /aa 或 /a:a 或 /a-d 或 /a:-d 只显示文件
rem /ad 或 /a:d 或 /a-a 或 /a:-a 只显示文件夹
rem /o 排序:N名称,S大小,E扩展名,D日期,G组目录优先,-逆序
批处理常常需要搜索并拷贝文件,所以需要从搜索到的文件路径中提取出路径和文件名。这可以利用循环和扩充字符串实现。上面介绍 for 循环时已经讲解了几种搜索文件的方法,现在讲解使用 /f 参数搜索文件的方法。
for /f %%i in ('dir /b/s/aa .') do (
echo %%~di %盘符:D:%
echo %%~fi %路径:D:\bat\example.bat%
echo %%~ni %不含扩展名的文件名:example%
echo %%~pi %所在文件夹路径(不含盘符):\bat\%
echo %%~si %短路径:D:\bat\example.bat%
echo %%~ti %修改日期:2023/06/29 下午 04:10%
echo %%~xi %扩展名:.bat%
echo %%~zi %字节大小:1006%
echo %%~dpi %所在文件夹路径:D:\bat\%
echo %%~sdpi %所在文件夹短路径:D:\bat\%
)
4.2 文件修改
5. 时间戳
set filename=%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%
set "filename=%filename: =0%"
echo %filename%
6. 类型转换
赋值命令 set 使用 /a 参数可以把等号后面的算术运算结果赋值给变量,利用这点可以实现数字与字符串的互转。
rem 字符串转数字
set str1=12
set str2=27
set /a num=str1+str2+31
rem 数字转字符串
set /a num1=1
set /a num2=2
set str=%num1%_%num2%
7. 函数定义
下面介绍怎么定义函数并传递参数。下面的代码定义了两个函数并分别传递 1 个参数、2 个参数。第一个函数前,要有一个 goto :eof 语句;每个函数后都要有一个 goto :eof 语句。
rem 下面是命令语句。
set a=1
set b=2
call :fun %a%
call :fac %a% %b%
rem 下面可以继续写命令语句。
rem 下面是函数定义。
goto :eof
:fun
echo %~0 %~1
goto :eof
:fac
echo %~0 %~1 %~2
goto :eof
bash 的参数都是引用传递,下面实现两个数相加的函数:c = a + b,注意 pause 语句的位置。
set a=1
set b=2
call :sum %a% %b% c
echo %c%
pause
goto :eof
:sum
set /a %~3=%~1 + %~2
goto :eof
8. 参考
- 扩充字符串,知乎专栏,2021。
- 批处理:文件遍历相关,CSDN,2019。
- 批处理(bat)遍历文件夹下所有文件,CSDN,2020。