Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

for ... do loop "wrap around"

Dec
47
2
for %f in (*.mkv) do (
echo %f >> "E:\Documents\Computer\Files Uploaded.txt"
)

This results in E:\Documents\Computer\Files Uploaded.txt having the following contents:

file1.mkv
file2.mkv
file3.mkv
file4.mkv
file1.mkv

Note that file1.mkv is there twice. After processing everything, the for...do loop "wraps around" back to the beginning. This is a minor annoyance and not a big deal.

However, in other batch files I use, I am doing a lot of other processing and renaming files in a very specific way. When the loop "wraps around" one or more files get processed again and it really screws things up.

As a work-around I include extra code that moves each file out of the directory after it is processed and then moves it back when finished. But that's kind of a pain and shouldn't be necessary.

This happens with TCC versions 24,25 and 26.
 
Last edited:
I'm still using version 25, and I do not see that behavior. I ran the following command:

for %f in (*.htm) do (echo %f >> junk.txt )

There were 49 matching files in the directory, and there were 49 line in junk.txt. I thought that perhaps the issue arose only when the command was broken over several lines, so I tried the same three-line version as in your example, and I again got the correct result. The variable %_for_files also had the correct value.

-- Jay
 
for %f in (*.htm) do (echo %f >> junk.txt )

It would be better to do:

(for %f in (*.htm) do echo %f ) >> junk.txt

so that junk.txt is kept open and not closed and reoped and repositioned...
 
I don't see it either (v26).

Code:
v:\test> dir /k /m /h
2020-07-29  17:01               0  file1.mkv
2020-07-29  17:01               0  file2.mkv
2020-07-29  17:01               0  file3.mkv
2020-07-29  17:01               0  file4.mkv

v:\test> for %f in (*.mkv) do (
More? echo %f >> "log.txt"
More? )

v:\test> type log.txt
file1.mkv
file2.mkv
file3.mkv
file4.mkv
 
Charles G.: I was just duplicating Dick Johnson's command to see if I experienced the problem he reported (I did not). Your command probably would have worked for him, since it did not have the compound command.

Dick: Do you see the problem with the simpler command

for %f in (*.mkv) do echo %f
 
Not reproducible here.

However, this sort of thing is not uncommon when processing files if you're also modifying / creating the file list at the same time. DO is doing a findfirstfile/findnextfile to get the file list, and if something else is simultaneously writing the directory, Windows can return the same file multiple times. You can get around this by using the /O: option in FOR, which will retrieve all of the files before doing any processing on the list.
 
Charles G.: I was just duplicating Dick Johnson's command to see if I experienced the problem he reported (I did not). Your command probably would have worked for him, since it did not have the compound command.

Dick: Do you see the problem with the simpler command

for %f in (*.mkv) do echo %f
No, I tried your "simpler version" and it worked fine. But that's the thing. The "wrap-around" problem does not occur 100% of the time. It happens frequently, but not 100%.

It just happened to me again today (using TCC 27.00.18 x64).

I have a batch file that I use to rename large groups of files in a very specific way. When I ran it today, it renamed everything perfectly, but then "wrapped around" and processed the first file again, completely screwing up the file name.

I will try the /O option with For, as recommended by rconn.

edit: Well, what do you know. It's right there in the documentation.

"The /O:... option saves all of the matching filenames and then performs the requested operation. This avoids the potential problem of processing files more than once."

Of course, you have to know where to look, and what you're looking for. :)
 
Last edited:
This kind of issue is inherent to FindFirstFile / FindNextFile, not just to TCC. If you make changes to the directory in question between FindNextFile calls, those changes may or may not be reflected in later FindNextFile calls, depending on a number of factors including the exact contents of the directory and even the file system of the drive being modified.
 
Another option is to execute the DIR command and capture its output and work from that list.
Code:
do f in /p dir /b *.mkv (echo %f)
for /F %%f in ('dir /b') do echo %%f
 

Similar threads

Back
Top