【WINDOWS / DOS 批处理】for命令详解(二)

本文详细介绍了FOR命令的格式二,包括%variable参数、cmd参数、cmd-parameters参数、/R [ [drive:]path] 参数和set参数的用法。通过多个示例和应用场景,阐述了如何在批处理中递归遍历文件和目录,以及如何处理通配符和转义字符。内容适用于Windows服务器运维和批处理脚本编写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 for命令详解(一)【共十篇】   

 for命令详解(二)【共十篇】

 for命令详解(三)【共十篇】

 for命令详解(四)【共十篇】

 for命令详解(五)【共十篇】           

 for命令详解(六)【共十篇】

 for命令详解(七)【共十篇】   

 for命令详解(八)【共十篇】 

 for命令详解(九)【共十篇】  

 for命令详解(十)【共十篇】 

 【格式二】

   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>

写作不易,本文档如能帮到您,麻烦您 “在下面一圈三连”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值