At what point does `for` or` for / R` list the directory (tree)?

The for command can be used to list the directory and apply (a) specific commands for each item. With /R you can do the same for a complete directory tree.

What happens when the contents of a numbered directory (tree) are changed by the command (s) in the body of the for command?

Suppose we have a D:\data directory with the following contents:

 file1.txt file2.txt file3.txt 

The output for %F in ("*.txt") do echo %F when executed in the specified directory explicitly displays the above list.

However, what is the result of the for loop when a command in the for body modifies the contents of a directory? For example, one of the files in the list is deleted, say file3.txt , before it is actually repeated? Or if a new file is created, for example file4.txt , before the loop ends?

How does for /R behave in this context? It is assumed that there are several subdirectories sub1 , sub2 , sub3 , each of which contains the above list of files; for /R sub2 through sub2 , sub1 already processed, but sub3 is not there yet; the contents of sub1 and sub3 change at this point (when passing through sub2 , as indicated); What will be listed then? I think sub1 content sub1 will not be recognized, but what about sub3 ?

Finally, is there a difference in the behavior of for or for /R when executed on the command line or from a batch file? Are there differences in different versions of Windows?

Note:
See also my similar question about the forfiles .

+6
source share
1 answer

This is a great question!

For a moment, focus on the simple for command. A known error is associated with this command when it is used to rename files. For instance:

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

In this case, often some files are renamed twice or even three times in certain cases. The problem is that this behavior depends on a number of factors that are not documented, for example, the position of the first renamed file inside the list of source files and several other points. Similarly, if a file is deleted before it is processed using for , the message β€œFile not found” is usually displayed (although not ALL). If a new file is created in the directory after running for , it may or may not be processed by for , depending (again) on a number of factors. The usual way to avoid the renaming problem is to force the for command to read the entire list of files first, and then process the list:

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

Thus, the changes that can be made to files on disk do not matter: the for /F command always processes the original list of files.

A similar problem occurs with the for /R command, but in this case, the likelihood of problems is greater because there are more directories in which dynamic changes can be made. Again: the exact behavior depends on a number of unknown factors, and the way to avoid them is through for /F ... in ('dir /S /B') . However, if you are really interested in this issue, I recommend that you conduct a series of tests on this issue (and publish the results). ;)

+6
source

All Articles