asc*_*pfl 6 for-loop cmd batch-file
该命令for
可用于枚举目录并对每个项目应用(a)某些命令.对于/R
完整的目录树,可以实现相同的功能.
当枚举目录(树)的内容被命令体中的for
命令改变时会发生什么?
假设我们的目录D:\data
包含以下内容:
file1.txt
file2.txt
file3.txt
Run Code Online (Sandbox Code Playgroud)
for %F in ("*.txt") do echo %F
在所述目录中执行的输出显然将反映上面的列表.
但是,for
当for
正文中的命令修改目录内容时,循环的输出是什么?例如,在file3.txt
实际迭代之前,列表中的一个文件被删除了吗?或者,如果file4.txt
在完成循环之前创建了一个新文件,例如?
for /R
在这种情况下表现如何?假定有几个子目录sub1
,sub2
,sub3
,每个包含的文件的上述列表; for /R
目前正在迭代sub2
,sub1
已经处理,但sub3
还没有; 那个时候的内容sub1
和sub3
改变(当前正sub2
如上所述走过的时候); 那将会列举什么?我猜,内容的变化sub1
不会被识别,但是怎么样sub3
?
最后,在命令提示符或批处理文件中执行for
或for /R
执行时的行为是否存在差异?不同的Windows版本有差异吗?
注意:
另请参阅我关于该命令的类似问题forfiles
.
这是一个很好的问题!
让我们专注于平常for
命令.当用于重命名文件时,存在与此命令相关的已知错误.例如:
set i=0
for %%a in (*.txt) do (
set /A i+=1
ren "%%a" !i!.txt
)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,经常会将某些文件重命名两次,在某些情况下甚至会重命名三次.问题是这种行为取决于一系列未记录的因素,例如原始文件列表中的第一个重命名文件的位置以及其他几个点.类似地,如果文件在被处理之前被删除for
,则通常会发出"未找到文件"消息(尽管不是所有时间).如果在开始执行后在目录中创建了新文件for
,那么它可能会或可能不会由for
依赖(再次)处理一系列因素.避免重命名问题的常用方法是强制for
命令首先读取整个文件列表然后 处理清单:
for /F "delims=" %%a in ('dir /B *.txt') do (
set /A i+=1
ren "%%a" !i!.txt
)
Run Code Online (Sandbox Code Playgroud)
这样,对磁盘中的文件可以进行的更改无关紧要:for /F
命令将始终处理原始文件列表.
for /R
命令会发生类似的问题,但在这种情况下,问题的可能性更大,因为有更多的目录可以进行动态更改.再说一次:确切的行为取决于一系列未知因素,避免它们的方法是通过for /F ... in ('dir /S /B')
.但是,如果您对这一点非常感兴趣,我建议您对该主题进行一系列测试(并发布结果).;)