在什么时候`for`或`for/R`枚举目录(树)?

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在所述目录中执行的输出显然将反映上面的列表.

但是,forfor正文中的命令修改目录内容时,循环的输出是什么?例如,在file3.txt实际迭代之前,列表中的一个文件被删除了吗?或者,如果file4.txt在完成循环之前创建了一个新文件,例如?

for /R在这种情况下表现如何?假定有几个子目录sub1,sub2,sub3,每个包含的文件的上述列表; for /R目前正在迭代sub2,sub1已经处理,但sub3还没有; 那个时候的内容sub1sub3改变(当前正sub2如上所述走过的时候); 那将会列举什么?我猜,内容的变化sub1不会被识别,但是怎么样sub3

最后,在命令提示符或批处理文件中执行forfor /R执行时的行为是否存在差异?不同的Windows版本有差异吗?

注意:
另请参阅我关于该命令的类似问题forfiles.

Aac*_*ini 6

这是一个很好的问题!

让我们专注于平常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').但是,如果您对这一点非常感兴趣,我建议您对该主题进行一系列测试(并发布结果).;)

  • 该信息取自各个站点的几篇帖子,例如[this one](http://stackoverflow.com/questions/15950081/windows-batch-file-loop-running-one-extra-iteration):“操作取决于完全取决于添加的前缀。以“a”开头的前缀与以“x”开头的前缀工作方式不同。结果取决于所使用的文件系统。NTFS 按字母顺序显示文件名,但 RAMDRIVE 上的 FAT 系统不会对文件名进行排序名称”。关于这一点的更详细描述是[此处](http://www.dostips.com/forum/viewtopic.php?f=3&t=4138&sid=463cb91964f497c478afcca79c33384a) (2认同)