计算机技术基础 (bat 批处理)Note6
本节主要讲解FOR命令语句(循环)在 bat 批处理中的使用 (part 2)
变量延迟 命令语句
在没有开启变量延迟的情况下,批处理命令行中的变量改变,必须到下一条命令才能体现。
使用变量延迟,变量需要用以对感叹号 !!
括起来。
变量延迟语句:setlocal enabledelayedexpansion
示例 1:
bat 批处理文件
set a=123 & echo %a%
echo %a%
set a=456 & echo %a%
echo %a%
pause
运行结果可以看到:第一行 set a=123 & echo %a%
这个 echo
打印不出来任何东西,因为这是被 &
链接起来的一条命令,这一条命令对 变量 a
的 set
定义变量要在这条命令执行完才会体现。即第二个 echo %a%
可以打印出来。同理第三条命令 (set a=456 & echo %a%
) 对 a
的重新 set
要等第三条命令执行完毕后才能体现,在第三条命令中的 echo
打印的变量a
依然是123,第四条命令 (echo %a%
) 再打印就会更改成新的 456
C:\Users\rwq119\Desktop\test>set a=123 & echo
ECHO is on.
C:\Users\rwq119\Desktop\test>echo 123
123
C:\Users\rwq119\Desktop\test>set a=456 & echo 123
123
C:\Users\rwq119\Desktop\test>echo 456
456
C:\Users\rwq119\Desktop\test>pause
Press any key to continue . . .
开启变量延迟之后,bat 文件
setlocal enabledelayedexpansion
set a=123&echo !a!
set a=456&echo %a%
echo %a%
pause
结果显示,第一行开启了变量延迟,这个bat脚本里可以使用变量延迟。第二行 set a=123 & echo !a!
使用了变量延迟 !a!
(注意一定要用 !!
括起来),这条命令会立即打印出来变量 %%a
的值 123。但是第三行没有使用变量延迟,变量依然使用 %%
,所以依旧没有更新变量值,打印 456。
C:\Users\rwq119\Desktop\test>setlocal enabledelayedexpansion
C:\Users\rwq119\Desktop\test>set a=123 & echo !a!
123
C:\Users\rwq119\Desktop\test>set a=456 & echo 123
123
C:\Users\rwq119\Desktop\test>echo 456
456
C:\Users\rwq119\Desktop\test>pause
Press any key to continue . . .
示例2:
@echo off
setlocal enabledelayedexpansion
For %%i in (1,2,3) do (
set a=%%i
echo %a%
echo !a!
)
pause
结果如下:
ECHO is off.
1
ECHO is off.
2
ECHO is off.
3
Press any key to continue . . .
首先我们要强调, for
语句虽然我们写的时候会拆分成多行,但事实上它会被认为成一行语句(一条命令)。之后正如结果所示,我们没有使用变量延迟的每次循环第二句 echo %a%
是无法打印出来的,因为在循环内定义的变量,循环执行完毕(for
语句整体是一条命令)才能体现。但是每次循环可以打印出 echo !a!
的值。
其他拓展:
启动批处理文件中环境变量本地化,本地化将持续到出现匹配的 endlocal
命令或者到达批处理文件结尾为止。
语法: setlocal {enableextensions | disableextensions} {enabledelayedexpansion | disabledelayedexpansion}
enableextensions
:启用命令扩展,直到出现匹配的endlocal
命令,无论setlocal
命令之前的设置如何。命令扩展包括一系列额外的批处理命令和功能,比如for /f
的高级功能、!变量!
的延迟扩展等。默认情况下,Windows 的 cmd.exe 是启用命令扩展的。disableextensions
:禁用命令扩展,直到出现匹配的endlocal
命令,无论setlocal
命令之前的设置如何。这将关闭所有由命令扩展提供的额外功能,使批处理文件的行为更加接近传统的 DOS 批处理。enabledelayedexpansion
:启用延迟的环境变量扩展,直到出现匹配的endlocal
命令,无论setlocal
命令之前的设置如何。这允许你在一个代码块(如if
语句或for
循环)内部修改一个变量,并立即通过!变量名!
语法使用修改后的值。(上文讲述)disabledelayedexpansion
:禁用延迟的环境变量扩展,直到出现匹配的endlocal
命令,无论setlocal
命令之前的设置如何。这将关闭延迟变量扩展功能,使得在代码块内部修改的变量不会立即生效。
整体来讲,我们可以单独使用setlocal
命令来启用或禁用命令扩展,也可以同时指定命令扩展和延迟变量扩展的状态。例如:
setlocal enableextensions enabledelayedexpansion
这将同时启用命令扩展和延迟变量扩展。如果我们想在批处理文件的某个特定点关闭这些功能,可以使用 endlocal
命令。endlocal
命令将结束由最近的 setlocal 命令创建的本地化环境设置,并恢复到之前的设置。
比如:
@echo off
setlocal enabledelayedexpansion
For %%i in (1) do (
set a=%%i
echo %a%
echo !a!
)
endlocal
For %%i in (1) do (
set a=%%i
echo %a%
echo !a!
)
pause
结果显示,当我们使用 endlocal
命令结束由最近的 setlocal 命令创建的本地化环境设置,并恢复到之前的设置后,下面的 echo !a!
不起作用了
ECHO is off.
1
ECHO is off.
!a!
Press any key to continue . . .
For /r
命令语句
For
参数 /r
命令说明:遍历文件夹,它会遍历指定目录和子目录下所有文件和文件夹,列举出文件夹和文件夹里面的所有文件。
示例1:
语法:for /r 目录 %%i in (元素集合) do 命令语句集合
如列举找到目标目录下所有:
for /r C:\target %%i in (*) do echo %%i
如列举找到目标目录下所有 .txt 文件:
for /r C:\target %%i in (*.txt) do echo %%i
For /d
命令语句
For
参数 /d
命令说明:列举出当前目录中的文件夹
示例:
for /d %%i in (C:\*) do echo %%i
这条命令会显示出 C盘下的文件夹,但不会显示文件夹里的文件和文件夹里的子文件夹。
For /l
命令语句
For
参数 /l
命令说明:计数循环
语法 for /l %%i in (x,y,z) do (....)
,在这个语句中,x
y
z
都只能取整数,正负皆可,x
代表起始值,y
代表增长,z
代表终止值,具体含义为:从 x
开始计数,以 y
为增长,直至最接近 z
的那个整数为止,这之间有多少个数,do
后面的语句就执行多少次。
语法要求:
实际上,x
,y
和 z
的值可正可负,甚至为0(y
除外),限制非常宽松。
- 步长
y
的值不能为 0 - 当步长
y
的值为正整数时,终止值z
不能小于初始值x
- 当步长
y
的值为负整数的时候,终止值z
不能大于初始值x
示例 bat 文件:
@echo off
for /l %%i in (-1,2,5) do echo processed_once
pause
结果显示了 4 次,从-1到5步长2一共有 -1,1,3,5 四个数字,所以执行四次。
processed_once
processed_once
processed_once
processed_once
Press any key to continue . . .
For
命令语句变量
命令说明:
~i
删除任何(事实上不是任何)引号(" "
),扩展%i
*%~fi
将%i
扩展到一个完全合格的路径名 *%~di
仅将%i
扩展到一个驱动器号%~pi
仅将%i
扩展到一个路径%~ni
仅将%i
扩展到一个文件名 *%~xi
仅将%i
扩展到一个文件扩展名%~si
扩展的路径只含有短名%~ai
将%i
扩展到文件的文件属性%~ti
将%i
扩展到文件的日期/时间
10.~$PATH:I
查找列在路径环境变量的目录,并将%I
扩展到找到的第一个完全合格的名称。如果环境变量名未被定义,或者没有找到文件,此组合键会扩展到空字符串
示例1 (for no.1):
我们有 txt 文本如下
"1111
"2222"
3333"
"4444"44
"55"55"55
bat文件如下:
@echo off
for /f %%i in (t.txt) do echo %%~i
pause
结果可以看到很多双引号 " "
被移除了,注意移除规律:
“1111 #字符串前的引号被删除
“2222” #字符串首尾的引号都被删除
3333” #字符串前无引号则后面的引号保留
"4444"44 #字符串前面的引号删除了,而中间的引号保留
"55"55"55 #字符串前面的引号删除了,而中间的引号保留
1111
2222
3333"
4444"44
55"55"55
Press any key to continue . . .
示例2 (for no.2):
显示C盘中所有的文件,文件夹(会显示完整的盘符和文件名)
for /f %%i in ('dir /b') do echo %%~fi
dir /b
是一个在Windows命令行(cmd)或批处理文件中使用的命令,用于显示目录中的文件和子目录的名称,但不显示其他信息,如文件大小、创建日期等。/b
参数代表“bare”或“basic”,意味着输出将仅包含文件名和目录名,没有任何额外的格式或信息。(如果想查看特定目录下的文件和子目录,可以这样做:dir /b C:\特定目录
)
所以只用 dir /b
的显示会类似:
使用 ~fi
:
示例3 (for no.5):
~ni
只会显示文件名,并不显示路径
备注:
这个是自学 b 站up主 程序员血月做的笔记。原视频链接:
https://space.bilibili.com/327484473/channel/seriesdetail?sid=2069394
因本人水平有限,如有任何问题,欢迎大家批评指正!