标题: [代码合集] 【原创】for命令-从入门到精通-简化版 [打印本页]
作者: 小程936 时间: 2016-6-2 22:17 标题: 【原创】for命令-从入门到精通-简化版
本帖最后由 小程936 于 2019-1-1 16:44 编辑
for命令-从入门到精通
(小程936原创,跟置顶帖没有一毛钱关系,我写这教程的时候根本不知道这个网站)
我相信大多数人对于for都是似懂非懂……主要原因就是,大部分教程求懒求快,直接复制for /?的机器翻译,导致基本没人看得懂,小部分教程堆砌辞藻,一句话能说完的事喜欢用不明觉厉的专业名称讲上几千字……本文承诺:绝不使用机器翻译帮助,不堆砌辞藻,祝大家学习愉快。
FOR函数,对一组文件批量执行命令,基本模式如下(ps:教程是给中国人看的,所以那种FOR %variable IN (set) DO command [command-parameters]教程写法我是绝对不会采用的)
1.文件搜索 for [/D] [/R [路径]] %%变量 in (集合) do (命令)
2.等差数列 for /L %%变量 in (开始,间隔,结束) do (命令)
3.文本处理 for /F ["选项"] %%变量 in (集合) do (命令)
注意:[A]表示可选,A|B表示多选,所以[方括号]和|符号是不用写到命令里的!
注意:【在批处理中使用 %%变量 ,在命令行中使用 %变量 ,记住了!】
详细的我们下一节再讲。
作业:按Win+R键运行cmd,输入以下命令试试(逐行复制,不要告诉我你连复制粘贴都不会),并试图理解for命令的写法- @ echo&cd /d C:/
- for /D %i in (*) do echo %i
- for /L %a in (1,1,5) do (start cmd)
- for /F "delims=" %p in ('dir /as /b') do (echo %p)
复制代码
1.批量执行 for [/D] [/R [路径]] %%变量 in (集合) do (命令)
/D 只搜索文件夹名[可选],若无该选项即为 只搜索文件名
/R [路径] 搜索子目录[可选]
路径 搜索指定目录[可选](这个鸡肋参数要求必须开启 搜索子目录 才能用,若想指定搜索目录普遍做法是先用cd /d跳转目录)若无该选项即为 搜索当前目录
%%变量 可以是一个字母(不区分大小写),数字,或符号,用于在命令中使用,代表搜索结果。
集合 指定一个或一组文件。可以使用通配符搜索。(允许指定多个搜索条件 用空格分隔 "带空格 的搜索条件用双引号括住")(当搜索条件不包含通配符时 不搜索直接输出 因此也可以用来指定文本 用空格分隔 "带空格 文本用双引号括住")(通配符*表示0个或多个字符,通配符?表示0个或1个字符)
命令 指定批量执行的命令。使用%%变量 指定搜索结果。- @ echo off
- for %%i in (*.bat) do (echo %%i)
- ::这段代码会显示当前文件夹(不含子文件夹)下所有的bat文件的文件名
-
- for %%i in (菜 芽 小 公 公) do echo %%i
- pause>nul
- ::这段代码会显示什么?试试看!
复制代码
注意:for搜索并不会搜索隐藏文件,因此若要搜索隐藏文件……过会儿再讲
作业:按Win+R键运行cmd,然后自行思索命令怎么写
1.搜索当前目录,目录名中包含es的目录,并显示出来
2.搜索子文件夹Desktop,包含子目录,并计算出该目录一共有多少文件。(set /a a+=1会用吧?不会就算了,显示出来也行)(本题不得使用cd跳转目录!)
3.分析下列代码,并尝试制作一个 [请输入多个数字,用空格隔开,输出这些数的乘积] 计算工具- set c=1
- for %%i in (2 3 5 7 11 13 17 19 23 29 31 37) do set /a c*=%%i
复制代码
2.等差数列 for /L %%变量 in (开始,间隔,结束) do (命令)
(开始,间隔,结束)表示从开始到结束的一个数列,间隔为数列差。因此,(1,2,10)将产生序列
(1 3 5 7 9),(5,-1,1)将产生序列(5 4 3 2 1)
[命令行]连续打开10个cmd窗口。- for /L %a in (1,1,10) do start cmd
复制代码
[批处理]生成一个100-200的数列,间隔为5- for /L %%a in (100 5 200) do echo %%a
复制代码
这个命令很简单啦,没啥解释的
作业:使用for /L命令制作一个[阶乘计算工具](10的阶乘=10*9*8*7*……*2*1)
上期答案
1.- for /D %i in (*es*) do (echo %i)
复制代码
2.- for /R Desktop %i in (*) do set /a a+=1
复制代码
3.- @echo off
- :1
- set /p a=请输入多个数字,用空格隔开=
- set c=1
- for %%i in (%a%) do set /a c*=%%i
- echo %a%的乘积=%c%
- goto 1
复制代码
答案仅供参考,不要求完全一致。
(楼主原创出品,刚刚写的)
上期答案- @echo off
- :1
- set /p a=请输入数字=
- set c=1
- for /L %%i in (1,1,%a%) do set /a c*=%%i
- echo %a%的阶乘=%c%
- goto 1
- 答案仅供参考,不要求完全一致。
复制代码
3.文本处理 for /F ["选项"] %%变量 in (集合) do (命令)
我们先说说选项。多个选项用空格分开,整体必须用双引号括起来。示例:- FOR /F "eol=; tokens=2,3* delims=," %%i in (myfile.txt) do @echo %%i %%j %%k
复制代码
可以使用的选项
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 >test.txt
- echo 第二行! 2,2 2,3 2,4 >>test.txt
- echo 第三行! 3,2 3,3 3,4 >>test.txt
- echo 第四行! 4,2 4,3 4,4 >>test.txt
- echo 在当前文件夹下生成了一个test.txt,内容为:
- for /F "delims=" %%i in (test.txt) do echo %%i
- echo 这个文件的第一列是:&pause>nul
- for /F %%i in (test.txt) do echo %%i
- echo 这个文件的第二列是:&pause>nul
- for /F "tokens=2" %%i in (test.txt) do echo %%i
- echo 这个文件的第三和第四列是:&pause>nul
- for /F "tokens=3-4" %%a in (test.txt) do echo %%a %%b
- echo 这个文件的第二行是:&pause>nul
- for /F "skip=1 delims=" %%i in (test.txt) do echo %%i&goto 1
- :1
- pause&echo 一大波僵尸即将袭来&pause&tasklist
- echo 去掉以上内容的前三行,仅保留第一列 & pause>nul
- for /f "skip=3" %%i in ('tasklist') do echo,%%i
- pause>nul
- 作业:仔细理解完 上方代码,融会贯通,举一反三。
复制代码
变量扩展
大家知道,在cmd中执行for命令,变量用%i表示,而在bat中,变量用%%i表示。(这是为什么呢?学完这课大家就会懂了)
1.变量的范围
数字计算[±21 4748 3647 整数],文本[8191个字节](set /p a=<文件 和 ^换行符 可突破该限制,暂不解释)
2.变量的命名
不允许使用纯数字
不建议使用单字母变量
命名不区分大小写
3.变量扩展-文本(以下示例均以变量%a%示范,实际变量名可以为任何值)
%a:文本1=文本2% 文本1替换为文本2(文本2可留空,如%a:文本1=%)
%a:*文本1=文本2% 可使用通配符 *零个或多个任意字符 ?一个任意字符
%a:~10% 第10个字之后的内容
%a:~-10% 倒数第10个字之后的内容
%a:~,5% 开头之后的5个字
%a:~,-5% 倒数第5个字之前的字
%a:~10,5% 第10个字之后的5个字
%a:~10,-5% 第10个字之后,倒数第5个字之前的字
%a:~-10,5% 倒数第10个字之后的5个字
%a:~-10,-5% 倒数第10个字之后,倒数第5个字之前的字
%a:~列数,位数%,表示保留 指定列 之后的 指定位
123456789---列数----987654321-
正数 负数
注:文本扩展在for命令中可能不可用
示范:set a=%a:~-10,-5%
4.变量扩展-路径(以下示例均以变量%a示范)
(此时右边%可以省略, %~a 和 %~a% 是一样的)
%a 路径 "Temp\tmp 12345.txt"
%~a 删除引号 Temp\tmp 12345.txt
%~fa 完整路径 D:\AppData\Local\Temp\tmp 12345.txt
%~da 分区 D:
%~pa 路径 \AppData\Local\Temp\
%~na 文件名 tmp 12345
%~xa 扩展名 .txt
%~sa 短文件名 D:\AppData\Local\Temp\TM3A8C~1.TXT
%~aa 文件属性 --a--------
%~ta 修改日期 2016/06/02 16:26
%~za 文件大小(字节) 18
%~$b:a 在 目录b 搜索 文件a 找到的第一个文件。
如果变量b不存在,或者没有找到文件a,返回空字符串。
需事先给变量b赋值,多个路径可用分号分隔。命令示例
set b=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem
可以组合使用来得到多重结果
%~dpa 分区和路径 D:\AppData\Local\Temp\
%~nxa 完整文件名 tmp 12345.txt
%~dp$b:a 在 目录b 搜索 文件a 输出 文件a 的 分区和路径
%~ftzaa 类似dir命令的输出(完整路径 日期 大小 属性)
--a-------- 2016/06/02 16:26 18 D:\AppData\Local\Temp\tmp 12345.txt
不组合拆分开也行,比如这样%~fa% %~ta% %~za% %~aa%
注意:路径扩展仅适用于%0 %1 …%9和for中的单字母变量%%i,若要支持其他变量,考虑使用call- @echo off & set a=百度贴吧。百度公司。中国公司
- echo %%0 %0
- echo 文本
- echo %%a%% %a%
- echo %%a:。=-%% %a:。=-%
- echo %%a:百度=%% %a:百度=%
- echo %%a:*公司=123%% %a:*公司=123%
- echo %%a:~5%% %a:~5%
- echo %%a:~-5%% %a:~-5%
- echo %%a:~,3%% %a:~,3%
- echo %%a:~,-3%% %a:~,-3%
- echo %%a:~5,3%% %a:~5,3%
- echo %%a:~5,-3%% %a:~5,-3%
- echo %%a:~-5,3%% %a:~-5,3%
- echo %%a:~-5,-3%% %a:~-5,-3%
- pause & echo 产生一个临时文件>tmp^ 12345.txt
- rem 使用上方办法即可创建带空格的文件
- Call :sub "tmp 12345.txt"
- rem 以上一条命令表示跳转到sub标签并将变量%1设置为"tmp 12345.txt"
- pause & Del "tmp 12345.txt" & goto tu
- :sub
- echo 路径
- echo %%1 %1
- echo %%~1 %~1
- echo %%~f1 %~f1
- echo %%~d1 %~d1
- echo %%~p1 %~p1
- echo %%~n1 %~n1
- echo %%~x1 %~x1
- echo %%~s1 %~s1
- echo %%~a1 %~a1
- echo %%~t1 %~t1
- echo %%~z1 %~z1
- echo %%~dp1 %~dp1
- echo %%~nx1 %~nx1
- echo %%~ftza1 %~ftza1
- echo. & Goto :eof
- :tu
- echo 特殊变量
- echo 当前目录%%CD%% %CD%
- echo 当前日期%%DATE%% %DATE%
- echo 当前时间%%TIME%% %TIME%
- echo 范围在0-32767的伪随机数%%RANDOM%% %RANDOM%
- echo 错误返回码%%ERRORLEVEL%% %ERRORLEVEL%
- echo cmd的版本号%%CMDEXTVERSION%% %CMDEXTVERSION%
- echo 显示当前打开cmd所用的命令%%CMDCMDLINE%% %CMDCMDLINE%
- echo 当前最高NUMA节点号%%HIGHESTNUMANODENUMBER%% %HIGHESTNUMANODENUMBER%
- pause
复制代码
5.变量扩展-延迟(在批处理开头加上一行etlocal enabledelayedexpansion即可)- @echo off
- set num=10
- set num=100 & echo %num%
- echo %num%
- echo 虽然已经将num的值更改为100,但由于没有延迟扩展,所以值仍为10,不过在下一个语句num的值就改变了
- pause
复制代码
- @echo off
- SetLocal EnableDelayedExpansion
- set num=10
- set num=100 & echo !num!
- echo 现在两个num的值一样了(注意%num%变成了!num!)
- echo %num%
- pause
复制代码
更复杂的写法
set q=!tem%c%!
set a=!aa:~%bb%,10!
set b=!a:%文本1%=%文本2%!
注意:延迟扩展与call的冲突- @echo off&setlocal enabledelayedexpansion
- call :1
- echo %a%&pause
- :1
- setlocal enabledelayedexpansion&echo 运行一遍,然后删除本行,再运行一遍。
- set a=欢迎光临
- exit /b
复制代码
保留第五行,输出错误结果;删除第五行,输出正确结果 欢迎光临
结论:使用call跳转标签或文件时,需确保目标无“setlocal enabledelayedexpansion”,否则将产生错误
若必须保留setlocal enabledelayedexpansion这一行,可参考解决方案- 方案1:
- @ echo off
- setlocal enabledelayedexpansion
- call :1 1
- echo %a%&pause
- :1
- if not #%*==# goto 2
- setlocal enabledelayedexpansion
- :2
- set a=欢迎光临
- exit /b
复制代码
- 方案2:
- @ echo off
- setlocal enabledelayedexpansion
- call :1
- for /F "delims=" %%i in (a) do set %%i
- echo %a%&pause
- :1
- setlocal enabledelayedexpansion
- set a=欢迎光临
- (set)>a
- goto :eof
复制代码
汇总小节
for [/D] [/R [路径]] %%变量 in (集合) do (命令)
文件搜索 文件夹 子文件夹 指定目录 单字母 搜索/文本 批量
for /L %%变量 in (开始,间隔,结束) do (命令)
等差数列 单字母 开始,间隔,结束 批量
for /F ["选项"] %%变量 in (集合) do (命令)
文本处理 选项 单字母 搜索/"文本"/'命令' 批量
for /F "eol=! skip=n delims= -x tokens=1,7-9* usebackq "
选项 注释 行 分隔符 列 新语法("搜索"/'文本'/`命令`)
%a:文本1=文本2% %a:~10,5% %CD% %DATE% %TIME% %RANDOM%
替换 截取 当前目录 日期 时间 随机数
高级用法
1.文件搜索
可以指定多个搜索目标,用空格隔开,比如这样(for命令会对每个搜索目标都搜索一遍)- for /D %i in (*es* a* Deskto?) do (echo %i)
复制代码
当没有搜索到目标时,输出搜索目标。因此for也支持 集合 内容为文本- for %%i in (菜 芽 "小 公 公") do echo %%i
复制代码
3.文本处理
使用goto跳转,即可实现只读取一行。- for /F "skip=3 delims=" %%i in (test.txt) do echo %%i&set a=%%i&goto 1
- :1
- for /F "skip=1 tokens=2 delims= " %%i in ('net user "%username%"') do set a=%%i&goto 2
- :2
- echo 中文用户名:%a: =%
复制代码
由于for /f支持读取 命令输出,所以for不能搜索隐藏文件的缺点可以借此部分修复。- for /f "delims=" %%i in ('dir /ah /s/b') do attrib "%%i" -s -h -r
复制代码
:) :) :) :) :) :) :)
结束----------------------------欢迎点右下角的评分按钮↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
作者: kongfuzhou 时间: 2016-6-3 16:01
太赞了 先收藏
作者: jrx401 时间: 2016-7-2 01:28
可否有 如下部分的使用实例呢?
4.变量扩展-路径(以下示例均以变量%a示范)
%~$b:a 在 目录b 搜索 文件a 找到的第一个文件。
作者: 小程936 时间: 2019-1-1 16:17
本帖最后由 小程936 于 2019-1-1 16:28 编辑
可否有 如下部分的使用实例呢?
4.变量扩展-路径(以下示例均以变量%a示范)
%~$b:a 在 目录b 搜索 文件a 找 ...
jrx401 发表于 2016-7-2 01:28
好的。- md %temp%\tem233 2>nul
- cd /D %temp%\tem233
- md a 2>nul
- md b 2>nul
- echo 333>"b\文件.txt"
- rem 创建临时文件夹和文件
- rem
- set uu=%temp%\tem233\a;%temp%\tem233\b
- call :测试 文件.txt
- pause
- call :测试 文件5.txt
- pause
- cd /D %temp%
- rd /S /Q tem233
- cmd
- :测试
- @echo.---%~$uu:1---
- @exit /b
复制代码
作者: 小程936 时间: 2022-4-9 14:05
这么好的帖子没人看,可惜了
作者: Batcher 时间: 2022-4-9 21:49
感谢分享!
作者: karmane 时间: 2022-4-10 23:03
上等干货啊
作者: 小程936 时间: 2022-8-18 12:08
作者: fzp070 时间: 2022-8-21 23:01
学习了,讲解的非常好,赞!
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |