【格式二】
FOR /R [ [drive:]path] ] %variable IN (set) DO cmd [cmd-parameters]
【注意】DO后面必须存在空白,即使do后面是左括号
【%variable参数】
variable 指定一个名称为单一字母的循环变量名,例如:%V,variable 区分大小写,所以 %V 不同于 %v。for命令用于批处理文件中时,%variable 必须写为 %%variable
【cmd参数】
指定对每个文件执行的命令
【cmd-parameters参数】
指定cmd的参数
【/R [ [drive:]path] ] 参数】
path 指定将要递归遍历的根目录名称
drive 指定 path 所在的驱动器,例如:C、D
/R [ [drive:]path ] 把 [drive:]path 指定为将要递归遍历的根目录,如果在 /R 后没有指定目录,则缺省值为当前目录。
- 如果 [drive:]path 在磁盘真实存在,则for命令会递归遍历它
- 如果 [drive:]path 在磁盘不存在,则 [drive:]path 被看作一个空目录
- 如果 [drive:]path 包含通配符,则for命令不报错且自动退出(没有任何输出)
- [drive:]path 只能指定单个目录
示例
demo.bat的内容如下:
::demo.bat
@echo off
for /r out %%a in (x.txt) do echo %%a
echo -------------------------------
for /r c:\out %%a in (x.txt) do echo %%a
echo -------------------------------
for /r c:\noDir %%a in (x.txt) do echo %%a
echo -------------------------------
for /r o?t %%a in (x.txt) do echo %%a
运行
C:\out>dir /s /b /a:d
C:\out\ziDir
C:\out\ziDir1
C:\out\ziDir\sun
C:\out\ziDir1\sun1
C:\out>dir /s /b /a:-d
C:\out\a.txt
C:\out\b.txt
C:\out\c.txt
C:\out\demo.bat
C:\out\rd
C:\out\ziDir\c.txt
C:\out\ziDir\sun\d.txt
C:\out>demo
C:\out\out\x.txt
-------------------------------
c:\out\x.txt
c:\out\ziDir\x.txt
c:\out\ziDir\sun\x.txt
c:\out\ziDir1\x.txt
c:\out\ziDir1\sun1\x.txt
-------------------------------
c:\noDir\x.txt
-------------------------------
C:\out>
【set参数】
在【格式二】中,set 被看作一个使用一个或多个空格分隔的文件名列表
工作原理
对于 set 中以空白分隔的每一个文件名,
- 如果它包括通配符,则在磁盘的 [drive:]path 目录下递归查找匹配它的文件,然后把找到的所有文件名分别:赋值给%variable,并执行 cmd [cmd-parameters];如果没有找到匹配它的文件,则for命令会忽略它;
- 如果它不包括通配符(这种情况下,for命令不会到磁盘中查找它,即:与它是否存在无关),则以 [drive:]path 为根目录,把递归到的所有子目录(包括隐藏目录)的完整路径名称,分别连接它,从而构成一个包含完整路径的文件名的列表,再把该列表的所有文件名分别:赋值给%variable,并执行 cmd [cmd-parameters]
【格式二命令功能】
- 要递归遍历当前目录下的非隐藏文件名,set中的文件名称必须使用通配符
- 在文件名前面添加当前目录中的所有目录,set中的文件名称不能使用通配符
1、set 是一个文件名列表,其中的文件名可以是不存在的
示例
demo.txt的内容如下:
::demo.bat
@echo off
for /r %%a in (aa bb) do (
echo %%a
)
运行
C:\out>tree /f . // tree命令不能显示隐藏目录和隐藏文件
卷 系统 的文件夹 PATH 列表
卷序列号为 B019-EC3F
C:\OUT
│ a.txt
│ demo.bat
│
└─ziDir
│ c.txt
│
└─sun
d.txt
C:\out>dir /b /a:hd
ziDir1
C:\out>demo
C:\out\aa
C:\out\bb
C:\out\ziDir\aa
C:\out\ziDir\bb
C:\out\ziDir\sun\aa
C:\out\ziDir\sun\bb
C:\out\ziDir1\aa
C:\out\ziDir1\bb
C:\out>
2、set 是一个文件名列表,其中的每个文件名(即使开头是驱动器开始的文件名)的位置都相对于/R参数指定的目录
示例
demo.txt的内容如下:
::demo.bat
@echo off
for /r c:\xyz %%a in (f:\aa d:\bb) do ( echo %%a )
运行
C:\out>demo
c:\xyz\f:\aa
c:\xyz\d:\bb
C:\out>
3、set 是一个文件名列表,如果它外面加双引号(或单引号或反引号),则会改变“原义”
示例
demo.txt的内容如下:
:: 本示例包含汉字,如执行乱码,请使用 Notepad++ 把本文档转化成ANSI编码 【标注一】
::demo.bat
@echo off
:: "x.txt y.txt"被看作一个文件名
for /r %%a in ("x.txt y.txt") do (
echo %%a
)
echo ------------------------------
:: 单引号被看作普通字符
for /r %%a in ('x.txt y.txt') do (
echo %%a
)
echo ------------------------------
:: 反引号被看作普通字符
for /r %%a in (`x.txt y.txt`) do (
echo %%a
)
【标注一】 下载Notepad++
运行
C:\out>dir /b /s /a:d
C:\out\ziDir
C:\out\ziDir1
C:\out\ziDir\sun
C:\out\ziDir1\sun1
C:\out>demo
C:\out\"x.txt y.txt"
C:\out\ziDir\"x.txt y.txt"
C:\out\ziDir\sun\"x.txt y.txt"
C:\out\ziDir1\"x.txt y.txt"
C:\out\ziDir1\sun1\"x.txt y.txt"
------------------------------
C:\out\'x.txt
C:\out\y.txt'
C:\out\ziDir\'x.txt
C:\out\ziDir\y.txt'
C:\out\ziDir\sun\'x.txt
C:\out\ziDir\sun\y.txt'
C:\out\ziDir1\'x.txt
C:\out\ziDir1\y.txt'
C:\out\ziDir1\sun1\'x.txt
C:\out\ziDir1\sun1\y.txt'
------------------------------
C:\out\`x.txt
C:\out\y.txt`
C:\out\ziDir\`x.txt
C:\out\ziDir\y.txt`
C:\out\ziDir\sun\`x.txt
C:\out\ziDir\sun\y.txt`
C:\out\ziDir1\`x.txt
C:\out\ziDir1\y.txt`
C:\out\ziDir1\sun1\`x.txt
C:\out\ziDir1\sun1\y.txt`
C:\out>
4、set 是一个使用一个或多个空格分隔的文件名列表,set 开头和末尾的空白(一个或多个空格)会被忽略
示例
demo.txt的内容如下:
::demo.bat
@echo off
set /a num=0
for /r %%a in ( aa bb ) do (
set /a num+=1
echo %%a
)
echo %num%
运行
C:\out>demo
C:\out\aa
C:\out\bb
C:\out\ziDir\aa
C:\out\ziDir\bb
C:\out\ziDir\sun\aa
C:\out\ziDir\sun\bb
C:\out\ziDir1\aa
C:\out\ziDir1\bb
8
C:\out>
5、set 是一个文件名列表,其中的每个文件名都可以使用通配符( * 、?),通配符只能匹配/R参数指定的根目录及其所有子目录下的非隐藏文件名(不能匹配目录名)
示例
demo.txt的内容如下:
::demo.bat
@echo off
:: x.txt和y.txt都不是真实存在的文件
for /r %%a in (x.txt *.txt) do (
echo %%a
)
echo -----------------------------------------------
:: a.txt存在于c:\out目录下,y.txt不是真实存在的文件
for /r %%a in (a.txt *.txt) do (
echo %%a
)
运行
C:\out>tree /f . // tree命令不能显示隐藏目录和隐藏文件
卷 系统 的文件夹 PATH 列表
卷序列号为 B019-EC3F
C:\OUT
│ a.txt
│ demo.bat
│
└─ziDir
│ c.txt
│
└─sun
d.txt
C:\out>dir /b /a:h b.txt
b.txt
C:\out>demo
C:\out\x.txt
C:\out\a.txt
C:\out\ziDir\x.txt
C:\out\ziDir\c.txt
C:\out\ziDir\sun\x.txt
C:\out\ziDir\sun\d.txt
C:\out\ziDir1\x.txt
-----------------------------------------------
C:\out\a.txt \\ 输出结果没有除重
C:\out\a.txt
C:\out\ziDir\a.txt
C:\out\ziDir\c.txt
C:\out\ziDir\sun\a.txt
C:\out\ziDir\sun\d.txt
C:\out\ziDir1\a.txt
C:\out>
6、 set 是一个文件名列表,其中的文件名支持转义字符(^)
示例
::demo.bat
@echo off
for /r %%a in (a^a bb cc) do (
echo a: begin-%%a-end
)
运行
C:\out>demo
a: begin-C:\out\aa-end
a: begin-C:\out\bb-end
a: begin-C:\out\cc-end
a: begin-C:\out\one two\aa-end
a: begin-C:\out\one two\bb-end
a: begin-C:\out\one two\cc-end
a: begin-C:\out\ziDir\aa-end
a: begin-C:\out\ziDir\bb-end
a: begin-C:\out\ziDir\cc-end
a: begin-C:\out\ziDir\sun\aa-end
a: begin-C:\out\ziDir\sun\bb-end
a: begin-C:\out\ziDir\sun\cc-end
a: begin-C:\out\ziDir1\aa-end
a: begin-C:\out\ziDir1\bb-end
a: begin-C:\out\ziDir1\cc-end
a: begin-C:\out\ziDir1\sun1\aa-end
a: begin-C:\out\ziDir1\sun1\bb-end
a: begin-C:\out\ziDir1\sun1\cc-end
C:\out>
【应用实例】
要求:
1、如果在当前目录下存在 myDir 目录,那么找出该目录(包括它的所有子目录)下的所有名为 a.txt 的非隐藏文件,并把它们的内容都换为只有一个行(行的内容:old)。
2、如果当前目录下不存在 myDir 目录,则建立 myDir\one\two 目录树,并在这些目录下面分别建立 a.txt(只有一个行吗,行的内容:new)。
思路:
要求1:需要在磁盘上查找文件,按照for命令格式二的工作原理:要在磁盘上查找文件,需要使 set 中的文件名包含通配符。
要求2需要在一个目录下递归建立文件,按照for命令格式二的工作原理:需要使 set 中的文件名不能包含通配符;
实现如下:
demo.bat是内容如下:
::demo.bat
@echo off
if not exist myDir (
md myDir\one\two
for /r myDir %%a in (a.txt) do ( echo new> %%a )
) else (
for /r myDir %%a in (a.txt?) do (
if %%~xa == .txt echo old> %%a
)
)
测试
C:\out>dir /b /a:d | findstr "myDir"
C:\out>demo
C:\out>type myDir\a.txt myDir\one\a.txt myDir\one\two\a.txt
myDir\a.txt
new
myDir\one\a.txt
new
myDir\one\two\a.txt
new
C:\out>del myDir\a.txt
C:\out>dir /s /b /a:-d myDir
C:\out\myDir\one\a.txt
C:\out\myDir\one\two\a.txt
C:\out>demo
C:\out>dir /s /b /a:-d myDir
C:\out\myDir\one\a.txt
C:\out\myDir\one\two\a.txt
C:\out>type myDir\one\a.txt myDir\one\two\a.txt
myDir\one\a.txt
old
myDir\one\two\a.txt
old
C:\out>
写作不易,本文档如能帮到您,麻烦您 “在下面一圈三连”。