`for` 或 `for/R` 在哪一点枚举目录(树)? [英] At which point does `for` or `for /R` enumerate the directory (tree)?

查看:21
本文介绍了`for` 或 `for/R` 在哪一点枚举目录(树)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

命令 for 可用于枚举目录并对每个项目应用 (a) 某些命令.使用 /R 可以为完整的目录树完成相同的操作.

The command for can be used to enumerate a directory and apply (a) certain command(s) on each item. With the /R the same can be accomplished for a full directory tree.

当枚举目录(树)的内容被 for 命令正文中的命令更改时会发生什么?

What happens when the content of the enumerated directory (tree) is changed by the command(s) in the body of the for command?

假设我们有目录D:data,内容如下:

Supposed we have the directory D:data with the following content:

file1.txt
file2.txt
file3.txt

for %F in ("*.txt") do echo %F 在上述目录中执行时的输出将明显反映上述列表.

The output of for %F in ("*.txt") do echo %F when executed in said directory will reflect the above list obviously.

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

However, what is the output of the for loop when a command in the for body modifies the content of the directory? For instance, one of the files in the list is deleted, let's say file3.txt, before it is actually iterated? Or if a new file is created, like file4.txt, before completion of the loop?

for/R 在这种情况下的表现如何?假设有几个子目录sub1sub2sub3,每个子目录都包含上面的文件列表;for/R 当前正在遍历sub2sub1 已经被处理了,但是sub3 还没有;sub1sub3 的内容在那一点发生了变化(当当前遍历 sub2 时);那么将枚举什么?我猜,sub1 内容的变化不会被识别,但是sub3 呢?

How does for /R behave in that context? Supposed there are several sub-directories sub1, sub2, sub3, each containing the above list of files; for /R is currently iterating through sub2, sub1 has already been processed, but sub3 not yet; the contents of sub1 and sub3 are changed at that point (when currently walking through sub2 as mentioned); what will be enumerated then? I guess, the change of the content of sub1 won't be recognised, but what about sub3?

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

Finally, is there a difference in behaviour of for or for /R when being executed in the command prompt or from a batch file? And are there differences in different Windows versions?

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

推荐答案

这是一个很好的问题!

让我们暂时专注于简单的 for 命令.当用于重命名文件时,有一个与此命令相关的已知错误.例如:

Let's concentrate on plain for command for a moment. There is a known bug related to this command when it is used to rename files. For example:

set i=0
for %%a in (*.txt) do (
   set /A i+=1
   ren "%%a" !i!.txt
)

在这种情况下,某些文件经常会被重命名两次,在某些情况下甚至会重命名三次.问题是这种行为取决于一系列未记录的因素,例如原始文件列表中第一个重命名文件的位置以及其他几个点.类似地,如果文件在 for 处理之前被删除,则通常会发出找不到文件"消息(尽管不是所有时间).如果在 for 开始执行后在目录中创建了一个新文件,那么它可能会或可能不会被 for 处理,这取决于(再​​次) 的一系列因素.避免重命名问题的常用方法是强制 for 命令首先读取整个文件列表,然后然后处理列表:

In this case is frequently that certain files be renamed twice, and even three times in certain cases. The problem is that this behavior depends on a series of factors that are not documented, like the position of the first renamed file inside the list of original files and several other points. Similarly, if a file is deleted before it is processed by the for, a "File not found" message is usually issued (although not ALL times). If a new file is created in the directory after the for started execution, then it may or may not be processed by the for depending (again) on a series of factors. The usual way to avoid the problem with rename is to force for command to first read the whole list of files and then process the list:

for /F "delims=" %%a in ('dir /B *.txt') do (
   set /A i+=1
   ren "%%a" !i!.txt
)

这样,可以对磁盘中的文件进行的更改无关紧要:for/F 命令将始终处理原始文件列表.

This way, don't matters the changes that can be made on the files in the disk: the for /F command will always process the original file list.

for/R 命令也会出现类似的问题,但在这种情况下,出现问题的可能性更大,因为可以进行动态更改的目录更多.同样:确切的行为取决于一系列未知因素,避免它们的方法是通过 for/F ... in ('dir/S/B').但是,如果您真的对这一点感兴趣,我鼓励您对该主题进行一系列测试(并发布结果).;)

A similar problem happen with for /R command, but in this case the possibility of problems is greater because there are more directories where dynamic changes can be made. Again: the exact behavior depends on a series of unknown factors and the way to avoid them is via for /F ... in ('dir /S /B'). However, if you are really interested in this point, I encourage you to made a series of tests on the subject (and post the results). ;)

这篇关于`for` 或 `for/R` 在哪一点枚举目录(树)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆