CMD批处理(4)——批处理循环语句结构
FOR函数,对⼀组⽂件批量执⾏命令,基本模式如下
1.⽂件搜索 for [/D] [/R [路径]] %%变量 in (集合) do (命令)
2.等差数列 for /L %%变量 in (开始,间隔,结束) do (命令)
3.⽂本处理 for /F ["选项"] %%变量 in (集合) do (命令)
⽂件搜索
命令⽤法:for [/D] [/R [路径]] %%变量 in (集合) do (命令)
/D 只搜索⽂件夹名[可选],若⽆该选项即为只搜索⽂件名
/R [路径] 搜索⼦⽬录[可选],如果在 /R 后没有指定⽬录规范,则使⽤当前⽬录。如果集仅为⼀个单点(.)字符,则枚举该⽬录树。
路径搜索指定⽬录[可选]
%%变量可以是⼀个字母(不区分⼤⼩写),数字,或符号,⽤于在命令中使⽤,代表搜索结果。在若是在命令⾏中⽤%(⼀个),批处理程序中使⽤ FOR 命令时,指定变量使⽤ %%(两个)。
集合指定⼀个或⼀组⽂件。可以使⽤通配符搜索。(允许指定多个搜索条件⽤空格分隔 "带空格的搜索条件⽤双引号括住")(当搜索条件不包含通配符时不搜索直接输出因此也可以⽤来指定⽂本⽤空格分隔 "带空格⽂本⽤双引号括住")
命令  指定批量执⾏的命令。使⽤%%变量指定搜索结果。
例1、显⽰当前⽂件夹(不含⼦⽂件夹)下所有bat⽂件的⽂件名
for %i in (*.bat) do echo %i
例2、计算game⽬录下及所有⼦⽬录下⼀共有多少⽂件
for /r game %i in (*) do set a+=1
例3、计算多个数字的乘积
@echo off
:
start
set /p n=请输⼊多个数字,⽤空格隔开:
set c=1
for %%i in (%n%) do set /a c*=%%i
echo %a%的乘积为%c%
goto :start
注意:for搜索并不会搜索隐藏⽂件
等差数列
命令⽤法:for /L %%变量 in (开始,间隔,结束) do (命令)
(开始,间隔,结束)表⽰从开始到结束的⼀个数列,间隔为数列差。因此,(1,2,10)将产⽣序列(1 3 5 7 9),(5,-1,1)将产⽣序列(5 4 3 2 1)
例1、连续打开⼗个cmd窗⼝
for /l %i in (1,1,10) do start cmd
例2、⽣成⼀个间隔为100-500的数列,间隔为5
for /l %i in (100,5,500) do echo %i
例3、计算阶乘
@echo off
:start
set /p n=请输⼊数字:
set c=1
for /l %%i in (1,1,%n%) do set /a c*=%%i
echo %n%的阶乘是%c%
goto :start
goto :start
⽂本处理
命令⽤法:for /F ["选项"] %%变量 in (集合) do (命令)
多个选项⽤空格分开,整体必须⽤双引号括起来。
eol=!  指定注释符号。默认未指定。(忽略以!开头的⾏)
skip=n 忽略第0-n⾏。默认为0(不忽略)
delims= -x 指定列分隔符,可指定多个。(将空格减号-字母x指定为列分隔符)(默认分隔符为空格制表符)(所谓制表符,打开记事本,按TAB键)
tokens=1,7-9* 读取第⼏列。默认为1。若命令为for /F "tokens=参数" %%a in (集合) do (命令)
当参数为1,7 变量a为第1列的内容,变量b为第7列的内容
当参数为7-9变量a为第7列的内容,变量b为第8列的内容,变量c为第9列的内容
当参数为9*变量a为第9列的内容,变量b为第9列之后所有列的内容
当参数为*变量a为所有列的内容。
当参数为1,7-9* 变量a为第1列的内容,变量b为第7列的内容,变量c为第8列的内容,变量d为第9列的内容,变量e为第9列之后所有列的内容。
看完这些,你已经明⽩tokens=怎么使⽤了吧?记住可⽤的三个符号,-*
usebackq 指定新语法。⽰范:for /F "usebackq" %%a in (集合) do (命令)
(集合) 指定⼀个或⼀组⽂件。可以使⽤通配符。(也可以指定⽂本或命令。)
usebackq 未启⽤  (⼀个或⼀组⽂本⽂档)   ("⽂本")    ('命令输出')
            (*.txt)     ("第⼀⾏ 1,2 1,3 1,4") ('dir /as /b')
usebackq 已启⽤  ("⼀个或⼀组⽂本⽂档")   ('⽂本')    (`命令输出`)
            ("*.txt")    ('第⼀⾏ 1,2 1,3 1,4') (`dir /as /b`)
"双引号" '单引号' `反单引号`
你可能觉得usebackq是⼀个可有可⽆,没有实际作⽤的选项?不要忘了,如果⽂件名中有空格,我们必须⽤双引号括起来!显然这会造成识别为⽂本……怎么办?启⽤usebackq呗~
额,说到这⾥,可能你还没弄懂for /F到底是啥……嗯,那就解释⼀下。
集合可以是  ⼀个或⼀组⽂件(⽂本⽂档) 或 "引号括起来的⽂本" 或 '命令输出'
(*.txt) ("第⼀⾏ 1,2 1,3 1,4") ('dir /as /b')
然后这些⽂本会逐⾏作为 %%变量进⾏输出
使⽤上⽅的选项设置,可以做到……忽略以某符号开始的⾏和忽略开头的数⾏和指定列分割符和只读取每⾏中的指定列。
多的不说,直接贴代码
例、
@echo off
echo 第⼀⾏! 1,2 1,3 1,4 &
echo 第⼆⾏! 2,2 2,3 2,4 >&
echo 第三⾏! 3,2 3,3 3,4 >&
echo 第四⾏! 4,2 4,3 4,4 >&
echo 在当前⽂件夹下⽣成了⼀个,内容为:
for /F "delims=" %%i in () do echo %%i
echo 这个⽂件的第⼀列是:&pause>nul
for /F %%i in () do echo %%i
echo 这个⽂件的第⼆列是:&pause>nul
for /F "tokens=2" %%i in () do echo %%i
echo 这个⽂件的第三和第四列是:&pause>nul
for /F "tokens=3-4" %%a in () do echo %%a %%b
echo 这个⽂件的第⼆⾏是:&pause>nul
for /F "skip=1 delims=" %%i in () do echo %%i&goto 1
:1
pause&cls&echo ⼀⼤波僵⼫即将袭来&pause&tasklist
echo 去掉以上内容的前三⾏,仅保留第⼀列 & pause>nul
for /f "skip=3" %%i in ('tasklist') do echo,%%i
pause>nul
扩展:setlocal enabledelayedexpansion
设置本地为延迟扩展。其实也就是:延迟变量,全称延迟环境变量扩展, 想进阶,变量延迟是必过的⼀关!
为了更好的说明问题,我们先引⼊⼀个例⼦。
例1、
批处理文件怎么做@echo off set a=4 set a=5&echo %a% pause
结果:4
解说:为什么是4⽽不是5呢?在echo之前明明已经把变量a的值改成5了?让我们先了解⼀下批处理运⾏命令的机制:批处理读取命令时是按⾏读取的(另外例如for命令等,其后⽤⼀对圆括号闭合的所有语句也当作⼀⾏),在处理之前要完成必要的预处理⼯作,这其中就包括对该⾏命令中的变量赋值。我们现在分析⼀下例1,批处理在运⾏到这句“set a=5&echo %a%”之前,先把这⼀句整句读取并做了预处理——对变量a赋了值,那么%a%当然就是4了!(没有为什么,批处理就是这样做的。)⽽为了能够感知环境变量的动态变化,批处理设计了变量延迟。简单来说,在读取了⼀条完整的语句之后,不⽴即对该⾏的变量赋值,⽽会在某个单条语句执⾏之前再进⾏赋值,也就是说“延迟”了对变量的赋值。那么如何开启变量延迟呢?变量延迟⼜需要注意什么呢?
举个例⼦说明⼀下:
@echo off
set a=4
set a=5&echo %a%
pause
解说:由于启动了变量延迟,得到了正确答案。变量延迟的启动语句是“setlocal enabledelayedexpansion”,并且变量要⽤⼀对叹号“!!”括起来(注意要⽤英⽂的叹号),否则就没有变量延迟的效果。分析⼀下例2,⾸先“setlocal enabledelayedexpansion”开启变量延迟,然后“set a=4”先给变量a赋值为4,“set a=5&echo !a!”这句是给变量a赋值为5并输出(由于启动了变量延迟,所以批处理能够感知到动态变化,即不是先给该⾏变量赋值,⽽是在运⾏过程中给变量赋值,因此此时a的值就是5了)。
例、查询本机计算机记录的wifi密码:
@echo off
:start
echo.> 1.txt
set c=
set n=
setlocal enabledelayedexpansion
echo 在本地计算机记录的wifi:
for /f "skip=3 tokens=2*" %%i in ('netsh wlan show profiles') do set /a c+=1 &echo !c!  %%j&echo !c! %%j>&
set /p n=请输⼊序号查看的wifi密码:
for /f "tokens=1* skip=%n%" %%i in (1.txt) do (
set var=%%j
echo %%j的密码是
netsh wlan show profiles name="%%j" key=clear | findstr 关键内容
goto :cc)
:cc
pause
cls
goto :start

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。