BAT变量:
set 不能用在复合语句里面
比如 `if 1==1 set a=2`
比如 `for %%i in (a) do set a=2`
::两个冒号后是注释,当然BAT注释好几种,我觉得这个最符合我的需要
::@本行不显示 Echo off 从此以后都不显示
@Echo off
::变量用set 声明并赋值(a=之间不能TMA的有空格,我被这个坑过)
::调用时%a%取出变量值
set a= 111
echo %a%
:: 取消变量。取消后的变量若被引用%变量名%将为空
set 变量名=
::列出所有以XX为前缀变量
set xx
::列出所有可用变量
set
::计算器
格式:set /a 表达式
示例:set /a 1+2*3 输出 7
::设置变量为表达式计算后的值
set a=1+2
echo %a% ==>输出1+2
------------------------------------
set /a a=1+2
echo %a% ==>输出3
::设置变量为用户输入的值
set /p a=输入一个值 ==>输出 输入一个值
echo %a% ==>显示用户输入的值
::暂停
pause
字符提取:
比如执行echo %time%
得到的显示时间为 18:57:44.10
即18点57分44秒10毫秒;
%time:~0,2% 是提取%time%中的前两个字符,即小时值;
%time:~3,2% 是从%time%中的第三个字符后开始提取两个字符,即分钟值;
%time:~6,2% 是从%time%中的第六个字符后开始提取两个字符,即秒数值;
字符提取问题可以set/?
查看中文帮助
举个例子吧!
set str=MyNameIsLuHongLein
echo %str:~2,4% //提取str中第二个字符后的四个字符,即显示 Name
echo %str:~-10% //显示str中最后十个字符,即 LuHongLein
echo %str:~2,-10% //从第二个字符后开始提取,但去除最后的十个字符,将显示 NameIs
BAT变量说明:
下面是网上抄来的常见的
set 功能一览
[设置变量]
格式:set 变量名=变量值
详细:被设定的变量以%变量名%引用
[取消变量]
格式:set 变量名=
详细:取消后的变量若被引用%变量名%将为空
[展示变量]
格式:set 变量名
详细:展示以变量名开头的所有变量的值
[列出所有可用的变量]
格式:set
[计算器]
格式:set /a 表达式
示例:set /a 1+2*3 输出 7
[设置变量为表达式计算后的值]
set a=1+2
echo %a% ==>输出1+2
------------------------------------
set /a a=1+2
echo %a% ==>输出3
[设置变量为用户输入的值]
set /p a=输入一个值 ==>输出 输入一个值
echo %a% ==>显示用户输入的值
!注意!
set不能用在复合语句里面比如if 1==1 set a=2或者for %%i in (a) do set a=2
() - 分组
! ~ - - 一元运算符
* / % - 算数运算符
+ - - 算数运算符
<< >> - 逻辑移位
& - 按位“与”
^ - 按位“异”
| - 按位“或”
= *= /= %= += -= - 赋值
&= ^= |= <<= >>=
, - 表达式分隔符
预定义的变量
下面是些已经被底层定义好可以直接使用的变量:不会出现在 SET 显示的变量列表中
%CD% - 扩展到当前目录字符串。
%DATE% - 用跟 DATE 命令同样的格式扩展到当前日期。
%TIME% - 用跟 TIME 命令同样的格式扩展到当前时间。
%RANDOM% - 扩展到 0 和 32767 之间的任意十进制数字。
%ERRORLEVEL% - 扩展到当前 ERRORLEVEL 数值。
%CMDEXTVERSION% - 扩展到当前命令处理器扩展名版本号。
%CMDCMDLINE% - 扩展到调用命令处理器的原始命令行。
%0 bat的完整路径名如"C:\Windows\system32\xxx.bat"
%1 bat参数1依次类推%2参数2...
%path% - 当前的环境变量。以分号隔开的路径列表,路径可包含空格,可以以'\'结尾, 可以以双引号包围之。
扩展变量
与%i相关的变量(bat参数或者for循环的%i)
假设文件为C:\Documents and Settings\jinsun\桌面\ParseSinglePkgs.bat
%0 C:\Documents and Settings\jinsun\桌面\ParseSinglePkgs.bat
%~dp0 C:\Documents and Settings\jinsun\桌面\
%cd% C:\Documents and Settings\jinsun\桌面
%~nx0 ParseSinglePkgs.bat
%~n0 ParseSinglePkgs
%~x0 .bat
Batch 参数
https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/call
下表列出了批处理脚本参数引用 (%0、 %1、...
) 。
%*
在批处理脚本中使用 值是指 (的所有参数,例如 %1、%2、%3...
) 。
可以使用以下可选语法作为批处理参数的替换 (%n
) :
参数 | 说明 | 例子 |
---|---|---|
%~1 | 展开 %1 并删除周围的引号。 | E:\projects\项目说明.md |
%~f1 | 将%1扩展到一个完全合格的路径名 | E:\projects\项目说明.md |
%~d1 | 仅将%1扩展到一个驱动器号 | E: |
%~p1 | 仅将%1扩展到一个路径 | \projects\ |
%~n1 | 仅将%1扩展到一个文件名 | 项目说明 |
%~x1 | 仅将%1扩展到一个文件扩展名(包括.) | .md |
%~s1 | 扩展的路径只含有短名 | E:\projects\项目说明.md |
%~a1 | 将%1扩展到文件的文件属性 | –a-------- |
%~t1 | 将%1扩展到文件的日期/时间 | 2022-11-26 15:22 |
%~z1 | 将%1扩展到文件的大小 | 3000 |
%~$PATH:1 | 查找列在路径环境变量的目录, 并将%1扩展到找到的第一个完全合格的名称。 如果环境变量名未被定义, 或者没有找到文件,此组合键会扩展到空字符串。 |
下表显示了如何将修饰符与复合结果的批处理参数组合在一起:
带修饰符的 Batch 参数 | 说明 |
---|---|
%~dp1 | 仅将 %1 展开为驱动器号和路径。 |
%~nx1 | 仅将 %1 展开为文件名和扩展名。 |
%~dp$PATH:1 | 在 PATH 环境变量中列出的目录 中搜索 %1,然后展开到找到的第一个目录的驱动器号和路径。 |
%~ftza1 展开 %1 | 以显示类似于 dir 命令的输出。 |
在上述示例中, %1
和 PATH
可以替换为其他有效值。 语法 %~
由有效的参数编号终止。 修饰 %~
符不能与 一起使用 %*
。
分支 if
1. IF EXIST 文件是否存在
@echo off
IF EXIST F:\test.bat (
echo 找到了
) ELSE (
echo 没找到
)
pause
2. not 条件否
批处理中没有 !=
、<>
这类不等于符号,需要求反时,在表达式前加 not
即可
@echo off
chcp 65001>nul
IF NOT EXIST F:\test.bat (
echo ( ╥╯︿╰╥ ^) 404
)
pause
3. if else 分支
根据输入内容判断跳转逻辑
@echo off
:star
set/p inputNumber= 输入数字,按回车继续 :
if "%inputNumber%"=="1" (
echo 111111111111111
) else if "%inputNumber%"=="2" (
echo 222222222222222
) else if "%inputNumber%"=="3" (
echo 333333333333333
) else if "%inputNumber%"=="Q" (
echo QQQQQQQQQQQQQQQ
) else (
echo 都不是。。。。。。。。。。
)
:again
set/p goon= 是否退出(Y/N)?
if "%goon%"=="Y" goto end
if "%goon%"=="y" goto end
goto star
:end
echo 成功结束
pause
4. IF not defined 如果变量未定义
IF not defined vpnIP (
echo VPN 地址没发现!
)
遍历 for
在批处理
程序中使用 FOR
命令时,指定变量请使用 %%i
而不要用 %i
。变量名称是区分
大小写的,所以 %i
不同于 %I
.
基础版本
FOR %i IN (set) DO command [command-parameters]
参数 | 说明 |
---|---|
%i | 用于记录,遍历过程中的,当前值的变量 |
(set) | 指定一个或一组文件。可以使用通配符。 |
command | 指定对每个文件执行的命令。 |
command-parameters | 为特定命令指定参数或命令行开关。 |
set
参数可以表示单个文件组或多个文件组。 可以使用通配符 (*
和?
) 指定文件集。 下面是有效的文件集:(带通配符
才进行匹配
,固定值
只会直接追加
在每个目录的末尾)
(*.doc)
(*.doc *.txt *.me)
(jan*.doc jan*.rpt feb*.doc feb*.rpt)
(ar??1991.* ap??1991.*)
in
和do
不是参数,但必须将它们与此命令一起使用。 如果省略其中任一关键字,将显示一条错误消息。
1. 遍历当前目录
下所有 bat
文件。
@echo off
for %%i in (*.bat) do (
echo %%i
)
echo.
pause
2. 遍历C:\aaa\
目录下所有 txt
文件。
@echo off
for %%i in (C:\aaa\*.txt) do (
echo %%i
)
echo.
pause
3. 遍历序列
逐个输出 1、2、3、4、5、6
@echo off
for %%i in (1 2 3 4 5 6) do (
echo %%i
)
echo.
pause
/D 遍历目录
FOR /D %variable IN (set) DO command [command-parameters]
遍历指定目录
下的目录
。支持通配符。如果带空格之类的特殊符号,用引号括起来。
@echo off
for /d %%i in ("c:\Program Files (x86)\M*") do (
echo %%i
)
echo.
pause
/R 递归遍历目录
FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
参数 | 说明 |
---|---|
[drive:]path | 开始遍历的根路径。不写默认当前目录 。 |
set | 如果集仅为一个单点(. )字符,则枚举该目录树。 |
1. 递归遍历当前路径下所有 java 文件
@echo off
for /r . %%i in (*.java) do (
echo %%i
)
echo.
pause
/L 遍历整数序列
FOR /L %variable IN (start,step,end) DO command [command-parameters]
参数 | 说明 |
---|---|
start | 起始值 |
step | 步长 |
end | 终值 |
该集表示以增量形式从开始到结束的一个数字序列:
(1,1,5)
将产生序列 1 2 3 4 5
,
(5,-1,1)
将产生序列 5 4 3 2 1
@echo off
for /L %%a in (1, 1, 5) do (
echo %%a
)
echo.
pause
/F 解析并处理:命令输出、字符串、文件内容
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
参数 | 说明 |
---|---|
options | 解析规则(如果解析拿到的内容) |
file-set | 从文件获取内容。 |
"string" | 对给定字符串进行解析。(双引号) |
'command' | 执行给定的命令,并对结果进解析。(单引号) |
fileset
为一个或多个文件名。继续到fileset
中的下一个文件之前, 每份文件都被打开、读取并经过处理。
处理包括读取文件,将其分成一行行的文字,然后将每行解析成零或更多的符号。然后用已找到的符号字符串变量值调用 For 循环。
以默认方式,/F 通过每个文件的每一行中分开的第一个空白符号。跳过空白行。 你可通过指定可选"options"
参数替代默认解析操作。这个带引号的字符串包括一个或多个指定不同解析选项的关键字。这些关键字为:
参数 说明 eol=# 指定 #
为行注释,以此字符开头的行将被忽略。(只支持一个字符)skip=n 忽略前 n
数。delims=xxx 指分隔符集。默认 空格
和制表符
。tokens=x,y,m-n 提取哪一列内容。 x
列和y
列用逗号,
分隔。m-n
表示一个范围。如果符号字符串中的最后一个字符星号*
,那么额外的变量将在最后一个符号解析之后分配并接受行的保留文本。usebackq 指定新语法以便在下类情况中使用:
1.命令
用反引号
。
2.字符串
用单引号
3.文件名
用双引号
。
- 如果使用了
usebackq
选项。引号用法变化 :FOR /F ["options"] %variable IN ("file-set") DO command [command-parameters] FOR /F ["options"] %variable IN ('string') DO command [command-parameters] FOR /F ["options"] %variable IN (`command`) DO command [command-parameters]
1. 遍历命令输出
- 先
dir
查当前目录,获取所有内容,但只显示名称。 - 遍历查出来的结果。判断如果是
目标文件
,就打印输出。
@echo off
@rem 解决读取文件内容中文乱码的问题。当前bat需要保存为utf-8
chcp 65001
@cls
@rem 获取当前路径
SET CURRENT_DIR=%~dp0
@rem 目标文件名
SET target="项目说明.md"
:: dir 递归查询当前目录下所有子目录,每个结果赋给 i
:: /b 使用空格式(没有标题信息或摘要,只有名称)。
:: /s 显示指定目录和所有子目录中的文件。
:: /ad a显示具有指定属性的文件, d目录
for /f %%i in ('dir /b "%CURRENT_DIR%"') do (
:: 找到目标文件,则输出
IF "%%i"==%target% (
echo %%i
)
)
echo.
pause
2. 遍历字符串
%i
在 for 语句中显式声明,%j
和%k
是通过tokens=
选项隐式声明
的。可以通过tokens=
一行指定最多 26
个符号,只要不试图声明一个高于字母"z"
或"Z" 的变量。请记住,FOR
变量是单一字母
、分大小写
和全局
的变量;而且,不能同时使用超过 52 个。
@echo off
for /f "tokens=1,2-3,4,* delims= " %%i in ("a b c d e f g") do (
echo i: %%i
echo j: %%j
echo k: %%k
echo l: %%l
echo m: %%m
)
echo.
pause
输出结果:
i: a
j: b
k: c
l: d
m: e f g
3. 遍历文件内容
逐行遍历文件内容,并按给定的分隔增拆分成列,并赋值给变量 %%i
@echo off
:: 解决读取文件内容中文乱码的问题。当前bat需要保存为utf-8
chcp 65001
@cls
:: usebackq 选项允许文件名用引号。默认双引号中的内容当字串会被直接解析(注释不要以中文结节,容导致出错)
for /f "usebackq eol=# skip=1 tokens=1,2-3,4,* delims= " %%i in ("文字.txt") do (
echo i: %%i
echo j: %%j
echo k: %%k
)
echo.
pause
FOR 变量提取:路径、文件名
FOR 变量参照的替换已被增强。你现在可以使用下列选项语法:
@echo off
set var=E:\projects\项目说明.md
for /f "delims=" %%I in ("%var%") do (
echo %%~I
详见下表...
)
这部分与上面 Batch 参数 规则一样。
只不过把 bat 参数的 %0、%1、%2、%3
换成了 for 变量 %%I、%%J、%%K
。
示例
情景:文件里有一堆 文件名.pvr.ccz 文件,要找出来改成png
遍历文件夹
- 先查文件夹下的.ccz 加了/s会遍历子文件夹,加了/b 只显示文/夹名
- 用 in(*.ccz) 的话可以不 /f 但是这样不知道怎么 遍历子文件夹了
- 然后再for一次去掉.pvr
@echo off
for /f %%i in ('dir /b/s *.ccz') do (
for /f "tokens=1,* delims=." %%a in ("%%i") do (
gametools pvr -save in#%%a.pvr.ccz out#%%a.png
del %%i
)
)
pause
@echo off
for %%i in (*.plist) do (
echo 文件名: %%~ni.plist
gametools plist -unpack in#%%~ni.plist out#%%~ni
)
pause
拖拽文件
1. 拖拽 2 个文件到 bat 上
:: 打印第 0 个参数。也就是当前 bat 文件。(完整路径)
echo %~0
:: 打印批处理后第 1 个参数。(如果是拖拽上来的文件,显示完整路径)
echo %~1
:: 打印批处理后第 2 个参数。(如果是拖拽上来的文件,显示完整路径)
echo %~2
pause
2. 遍历拖拽上来的所有文件
不包括 bat 自己。
@echo off
for %%i in (%*) do (
echo %%i
echo.
)
pause
遍历当前目录及子目录
dir /S 显示指定目录和所有子目录中的文件。
@echo off
for /f "delims=" %%i in ('dir /b/s *.*') do (
echo %%i
)
pause
批处理中分割字符串【转】
把一个字符串按照特定的字符分割成多个子字符,一般的编程语言中都提供内置的方法来实现这个功能,在批处理中可以通过命令for来完成。命令格式如下:
for /f "tokens=x,y,m-n delims=chars" %%a in ("str") do cmd
其中tokens获取分割后字符串的列数,列数从1开始技术,可以指定多个,中间用“,”分割。tokens设置具体含义如下:
tokens=x 表示只提取第x列。
tokens=x,y 表示只提取第x列和第y列。
tokens=m-n 表示提取第m列至第n列。
tokens=x* 表示提取第x列和后面所有字符串都作为第x+1列。
tokens=x,* 等同tokens=x*
tokens=x,y,m-n 表示提取第x,y列以及第m至第n列。
一个简单例子如下:
@echo off
set str=100x200x300y400y500x600y700
for /f "tokens=1,3-5,* delims=x|y" %%a in ("%str%") do (
set c1=%%a
set c3=%%b
set c4=%%c
set c5=%%d
set c6=%%e
)
echo %c1%, %c3%, %c4%, %c5%, %c6%
pause
输出结果为:100, 300, 400, 500, 600y700
。
其中tokens=1,3-5,*
表示提取第1、3
至5
列,
同时把第5
列后所有剩余字符串作为第6
列,一共输出了5
个变量,
也可以写作 tokens=1,3,4,5,*
。
中文乱码
- 单文件处理
如果只有当前一个批处理文件,并且文件中有中文,只需要将当前文件另存并修改如下编码即可:
- 从当前文件外加载中文
此时上面的方法只能保证当前文件中的中文正常,但是如果在批处理中打开了别的UTF-8
文件,里面的中文一样是乱码。加上chcp 65001
,同时当前文件要存成utf-8
。
@echo off
:: 解决读取文件内容中文乱码的问题。当前bat需要保存为utf-8
chcp 65001>nul
更改活动控制台代码页。 如果使用不带参数, chcp 显示活动控制台代码页的数目。
代码页 | 国家/地区或语言 |
---|---|
437 | United States |
略… | 详见:受支持的代码页及其国家/地区或语言 |
936 | 简体中文,默认GBK |
950 | 繁体中文 |
65001 | UTF-8代码页 |
设置环境变量
%PATH%
后是否要加;
根据你自己的实际情况而定,一般我每次向PATH
追加内容时,都使用;
结尾了,所以我可以不加。
如果你PATH
的当前值没有以;
结尾,那拼接时记得加一下。PATH
值太长的时候会报错。乖乖手动操作系统属性》高级》环境变量
警告: 正保存的数据被裁断到 1024 字符。
错误: 拒绝访问注册表路径。
设置临时变量
set JAVA_HOME=D:\JDK8_64
set PATH=%PATH%;%JAVA_HOME%\bin;
设置永久变量
- 用户环境变量
setx JAVA_HOME D:\JDK8_64
setx CLASS_PATH .;%JAVA_HOME%\lib;
setx PATH %PATH%;%JAVA_HOME%\bin;
- 系统环境变量
setx /M JAVA_HOME D:\JDK8_64
setx /M CLASS_PATH .;%JAVA_HOME%\lib;
setx /M PATH %PATH%%JAVA_HOME%\bin;
命令实例
copy 内涵图
实现 图片 + zip = 图片
内涵图。
copy /b 图片.gif /b + 压缩包.zip /b 结果图片.gif
subst 目录挂载为驱动器
挂载e:\_f
目录为 F
盘
subst f: e:\_f
删除挂载的盘符 F
subst f: /d
参考资料
MSDN:命令行语法关键字
MSDN:服务器角色的命令
MSDN:Windows 命令
MSDN:Docs / Windows Server / Windows 命令 / 服务器角色命令 / for