I've written the following batch file to create multiple files using FOR loop:
@echo off cls FOR /L %%i IN (1 1 10) DO ( echo.> file%%i.txt IF ERRORLEVEL 0 echo Successfully created file 'file%%i.txt'. ) dir /b *.txt FOR %%i IN (*.txt) DO ( echo.> file%%i.txt IF ERRORLEVEL 0 echo Successfully created file 'file%%i.txt'. )
Here, 10 files (viz. file1.txt
.... file10.txt
) are created in the first FOR loop.
And in the second FOR loop I've used these files to frame the name of next new files. (viz.filefile1.txt.txt
... filefile10.txt.txt
)
But, an extra file is being created : filefilefile1.txt.txt.txt
What logical issue is causing the creation of this extra file ?
Like adarshr said, the second FOR loop can find even the new created files.
You can avoid this by using FOR/F with a command, as the result of the dir is completely fetched before the body of the loop is executed.
EDITED - Seems i've not explained it properly and people doesn't see how it works. My fault. I'm going to try to explain it better.
The reason is the way the for command works internally.
When the line
for var in (files)
is reached, the directory is checked to see if any files match and need to be processed.Then,
for
command (cmd really), issues a directory query to enumerate the files. This query returns only the first file in set. If there are any aditional files that match the file mask infor
command, a flag is set that indicates to the caller (cmd) that there are more files to be processed, but the list of the remaining files is not yet retrieved.When execution of code inside
for
reachs the end of an iteration, and there are files pending to be read, a query is sent to get the remaining of the list of files pending to be processed and that match thefor
file selection.System fills a buffer with the list of files remaining. If at that point the list of files is short enough to be full readed in buffer, the query will not be repeated. If the list of files is big enough to not fit in buffer, partial list is retrieved and when files in retrieved list are processed, the query will be sent again to get more files to process.
Number of files in buffer depends on length of filename. Shorter filenames, more files in buffer and less queries to filesystem.
This behaviour (retrieving remaining list of files at end of first file processing) is only done if the query for files returns that there are files pending. When one query does not return that flag, no more files are retrieved.
EXCEPTIONS
If working in NTFS, the files only get included in "requeries" if they are alphabetically greater than the last file that has been processed in
for
command.If working if FAT, the query will include all new file generated that match the
for
command file selection independly of it name. And yes, it can get into an infinite loop. (In tests, the system buffer only retrieve one filename, and requery in each iteration). You can tryAll my tests has been made on a windows 7 64bit, NTFS and FAT32 partition (this on a USB drive). No way to test other configurations. If anyone see a diferent behaviour, please comment.
For more information, ZwQueryDirectoryFile
I don't know why, but when you write
... IN (*.txt) ...
in the secondfor
loop, it is trying to find files that are just created within the body of the loop.To eliminate that, I would make my filter a bit more specific.
I ran this and it creates only 20 files as expected.