摘自:http://bbs.bathome.net/thread-2189-1-1.html
将工作路径切换为.bat文件所在的位置
cd /d %~dp0
/b 显示文件夹或文件的名字
/s 显示指定目录和所有子目录中的文件。
@echo off
dir /s /b *.* > C:\Users\DELL\Desktop\test.txt
当然也可以使用for循环:
@echo off
for %%i in (*.*) do echo "%%i"
pause
下述代码会提取test.txt里的内容
@echo off
for /f %%i in (test.txt) do echo %%i
pause
for /f是以行为单位进行处理的,即每次for循环处理一行。
这段代码,主要是让你树立这样一种观念:读取文本文件的内容,请使用 for/f 语句!
下述命令是每输出一行就暂停!!!!!!!!!
@echo off
cd /d %~dp0
for /f %%i in (test.txt) do echo %%i&pause
pause
使用chcp 来修改编码
@echo off
chcp 65001
cd /d %~dp0
for /f "delims=, " %%i in (test.txt) do echo %%i
pause
1258 越南语
1257 波罗的语
1256 阿拉伯语
1255 希伯来语
1254 土耳其语
1253 希腊语
1252 拉丁 1 字符 (ANSI)
1251 西里尔语
1250 中欧语言
950 繁体中文
949 朝鲜语
936 简体中文(默认)
932 日语
874 泰国语
850 多语种 (MS-DOS Latin1)
437 MS-DOS 美国英语
65001 UTF-8
但是有一个问题需要注意,被处理的对象65001编码,这个.bat或才.cmd文件的编码应与之相同,否则会出现意想不到的问题
@echo of
for /f "delims=., " %%i in (test.txt) do echo %%i
pause
注意delims=后面跟着的是一个符号列表,也就是说可以不只一个符号。以上述例子为例,第一个点号或第一个逗号之前的内容都被提取出来了。
上述命令只提取第一个,如果需要自定义提取,则用token
@echo off
chcp 65001
cd /d %~dp0for /f "delims=, tokens=2,4" %%i in (test.txt) do echo %%i %%j
pause
上述命令有token=2,4表示提取第2个、第4个(从1开始),注意因为提取了两个,所以还要有%j
当然token可以连续写比如:
@echo off
chcp 65001
cd /d %~dp0for /f "delims=, tokens=3-5,6,7,9" %%i in (test.txt) do echo %%i %%j
pause
token=后面的东西可以怎么方便怎么写。
下面给出带星号的表示:
@echo off
for /f "delims=, tokens=1,*" %%i in (test.txt) do echo %%i %%j
pause
结果,第一个逗号不见了,取代它的是一个空格符号,其余部分保持不变。
其中奥妙就在这个星号上面。tokens=后面所接的星号具备这样的功能:字符串从左往右被切分成紧跟在之前的数值所表示的节数之后,字符串的其余部分保持不变,整体被所表示的一个变量接收。**
*上述代码的具体情况就是[txt2] 的内容被切分,切分符号为逗号,当切分完第一节之后,切分动作不再继续下去,因为 tokens=1, 中,星号前面紧跟的是数字 **1;第一节字符串被切分完之后,其余部分字符串不做任何切分,整体作为第二节字符串,这样, [txt2]就被切分成了两节,分别被变量%%i 和变量%%j 接收。
@echo off
for /f "skip=2" %%i in (test.txt) do echo %%i
pause
这段代码将跳过头两行内容,从第 3 行起显示 test.txt 中的信息
for /f 语句是默认忽略以分号打头的行内容的,正如它默认以空格键或跳格键作为字符串的切分字符一样。
所以在处理下述三行中,前两行会被跳过不显示任何东西
;论坛的目标是:不求最大,但求最好,做最实用的批处理论坛。
;论坛地址: bbs.bathome.cn。
这里是:新手晋级的福地,高手论剑的天堂。
若要改为其他字符,则可以按如下操作:
@echo off
for /f "eol=;" %%i in (test.txt) do echo %%i
pause
eol= 的准确含义是:忽略以指定字符打头的行。
usebackq 是一个增强型参数,当使用了这个参数之后,原来的 for语句中第一个括号内的写法要做如下变动:如果第一个括号里的对象是一条命令语句的话,原来的单引号’要改为后引号`;如果第一个括号里的对象是字符串的话,原来的双引号"要改为单引号’;如果第一个括号里的对象是文件名的话,要用双引号"括起来。w例子如下:
@echo off
for /f "usebackq" %%i in ("test 1.txt") do echo %%i
pause
1、当你希望读取文本文件中的内容的话,第一个括号中不用任何符号包裹,应该使用的是第 1 条语句;例如:你想显示 test.txt 中的内容,那么,就使用 for/f %%i in (test.txt) do echo %%i;
2、当你读取的是命令语句执行结果中的内容的话,第一个括号中的命令语句必须使用单引号包裹,应该使用的是第 2 条语句;例如:你想显示当前目录下批处理For 语句从入门到精通(bbs.bathome.net)文件名中含有 test 字符串的文本文件的时候,应该使用 for /f %%i in (‘dir /a-d/b test.txt’) do echo %%i 这样的语句;
3、当你要处理的是一个字符串的时候,第一个括号中的内容必须用双引号括起来,应该是用的是第 3 条语句;例如:当你想把 bbs.bathome.cn 这串字符中 的 点 号 换 为 短 横 线 并 显 示 出 来 的 话 , 可 以 使 用 for /f “delims=.tokens=1-3” %%i in (“bbs.bathome.cn”) do echo %%i-%%j-%%k 这样的语句。
1、 for /f %%i in (文件名) do („„)
2、 for /f %%i in (‘命令语句’) do („„)
3、 for /f %%i in (“字符串”) do („„)
4、 for /f “usebackq” %%i in (“文件名”) do („„)
5、 for /f “usebackq” %%i in (命令语句
) do („„)
6、 for /f “usebackq” %%i in (‘字符串’) do („„)
setlocal enabledelayedexpansion
类似verilog里的阻塞赋值,如果不设置就相当于非阻塞赋值了。举例如下:
@echo off
set num=0
setlocal enabledelayedexpansion
for /f %%i in ('dir /a-d /b *.exe') do (
set /a num+=1
echo num 当前的值是 !num!
)
echo 当前目录下共有 %num% 个 exe 文件
dir /a-d /b *.txt|findstr "test">nul&&(
echo 存在含有 test 字符串的文本本件)||echo 不存在含有 test 字符串的文本文件
if exist test.ini (
echo 存在 test.ini 文件)
else 不存在 test.ini 文件
pause
由此可见,如果使用 setlocal enabledelayedexpansion 语句来延迟变量,就要把原本使用百分号对闭合的变量引用改为使用感叹号对来闭合;如果使用 call
语句,就要在原来命令的前部加上 call 命令,并把变量引用的单层百分号对改为双层。 其中,因为 call 语句使用的是双层百分号对,容易使人犯迷糊,所以用得较少,常用的是使用 setlocal enabledelayedexpansion 语句(set 是设置的意思, local 是本地的意思, enable 是能够的意思, delayed 是延迟的意思, expansion是扩展的意思,合起来,就是:让变量成为局部变量,并延迟它的扩展行为)。
1、怎样使用变量延迟?
方法有两种:
① 使用 setlocal enabledelayedexpansion 语句:在获取变化的变量值语句批处理 For 语句从入门到精通(bbs.bathome.net)之前使用 setlocal enabledelayedexpansion,并把原本使用百分号对闭合的变量引用改为使用感叹号对来闭合;
② 使用 call 语句:在原来命令的前部加上 call 命令,并把变量引用的单层百分号对改为双层。
此命令用于递归地遍历文件夹
for /r 目录 %%i in (元素集合) do 命令语句集合
举例如下:
@echo off
for /r d:\test %%i in (.) do echo %%i
pause
但是我们知道 1.2节里指出dir也可列出文件夹,那么两者有什么区别呢?
1、 for /r 列举出来的路径最后都带有斜杠和点号,而 dir 语句则没有,会对获取到的路径进行进一步加工产生影响;
2、 for /r 不能列举带隐藏属性的目录,而 dir 语句则可以通过指定 /a 后面紧跟的参数来获取带指定属性的目录,更加灵活;
3、若要对获取到的路径进行进一步处理,则需要把 dir 语句放入 for /f 语句中进行分析,写成 for /f %%i in (‘dir /ad /b /s’) do „„ 的形式;由于 for /r 语句是边列举路径边进行处理,所以,在处理大量路径的时候,前期不会感到有停顿,而 for /f 语句则需要等到 dir /ad /b /s 语句把所有路径都列举完之后,再读入内存进行处理,所以,在处理大量路径的时候,前期会感到有明显的停顿
1、 for /r:
1)优点:
① 只通过 1 条语句就可以同时实现获取目录路径和处理目录路径的操作;
② 遍历文件夹的时候,是边列举边处理的,获取到一条路径就处理一条路径,内存占用小,处理大量路径的时候不会产生停顿感;
2)缺点:
① 不能获取到带隐藏属性的目录,会产生遗漏;
② 不能获取带指定属性的目录
2、 dir /ad /s:
1)优点:
① 能一次性获取带任意属性的目录,不会产生遗漏;
② 能通过指定不同的参数获取带任意属性的目录,更具灵活性。
2)缺点:
① dir /ad /s 语句仅能获取到目录路径,若要实现进一步的处理,还需要嵌入 for /f 语句中才能实现,写法不够简洁;
② 嵌入 for /f 语句之后,需要写成 for /f “delims=” %%i in (‘dir /ad /b /s’)do „„ 的格式,受 for /f 语句运行机制的制约,需要先列举完所有的路径放入内存之后,才能对每一条路径进行进一步的处理,处理大量路径时,内存占用量偏大,并且在前期会产生明显的停顿感,用户体验度不够好;
综上所述,还是尽量使用dir命令吧
它仅能匹配当前目录下的第一级文件夹,或是指定位置上的文件夹,而不能匹配更深层次的子文件夹。例如: for /d %%i in (d:\test*) do echo %%i 这样的语句 ,会匹配到形如:d:\test、 d:\test1、 d:\test2 之类的文件夹,若不存在这样的路径,将不会有任何回显
其中l是loop的意思,意为循环
for /l %%i in (1,2,10) do echo bathome
在以上的代码中,初始值是 1,步长为 2,终止值为 10,表明计数从 1 开始,每隔 2 个数计算一次,直至最接近 10 的那个整数,罗列出来,就是 1,3,5,7,9,再下一个就是 11,超过 10 了,不再计算在内,所以, do 后的语句只执行 5 次,将连续显示 5 个 bathome。
实际上, x, y 和 z 的值可正可负,甚至为 0,限制非常宽松:
1、步长 y 的值不能为 0;
2、当步长 y 的值为正整数时,终止值 z 不能小于初始值 x;
3、当步长 y 的值为负整数的时候,终止值 z 不能大于初始值 x。
换而言之,必须保证 in 和 do 之间能取到一个有效的数组序列。
for /l %%i in (-1,2,5) do echo bathome
for /l %%i in (5,-2,-1) do echo bathome
以上两条代码的功能完全一样,都将显示 4 次 bathome,区别就在于是正序计数、逆序计数而已。
当循环次数确定的时候,首选 for /l 语句,也可使用 goto语句但不推荐;当循环次数不确定的时候,用 goto 语句将是唯一的选择,因为,这个时候需要用 if 之类的条件语句来判断何时结束 goto 跳转。