Cmd For loop is allergic to certain file names

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Redwood
Posts: 3
Joined: 08 Sep 2019 05:20

Cmd For loop is allergic to certain file names

#1 Post by Redwood » 08 Sep 2019 05:28

I can finally add a date at the beginning to a series of files located in one folder.

I use this :

Code: Select all

@set var1="2011.01.15 "
@set var2=
@set var3=
@for %%i in (*.txt) do call :extra %%i
@goto :eof

:extra
@set var2=%1
@set var3=%var1%%var2%
@ren %var2% %var3%
@echo "-----"
with these three files in the folder it works 0123.txt, 2222.txt, 3333.txt

D:\X>call :extra 0123.txt
"-----"
D:\X>call :extra 2222.txt
"-----"
D:\X>call :extra 3333.txt
"-----"

but...when the files are named 0123.txt, 0222.txt, 3333.txt, the for loop performs an extra iteration with the first file which
has already been renamed. Very strange.

D:\X>sol2

D:\X>call :extra 0123.txt
"-----"
D:\X>call :extra 0222.txt
"-----"
D:\X>call :extra 2011.01.15 0123.txt
Das System kann die angegebene Datei nicht finden. (can't find the file)
"-----"
D:\X>call :extra 3333.txt
"-----"

Why is this code allergic to a second file with a leading '0' character?

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Cmd For loop is allergic to certain file names

#2 Post by aGerman » 09 Sep 2019 01:33

There are several things in your code that make me wonder that it actually works most of the time.
However, I already saw this behavior in simple FOR loops as well as in FOR /D and FOR /R loops. It seems that the list of found files are not buffered internally. It may happen that already renamed files are found again. Try to process the output of DIR /B in a FOR /F loop. This should buffer the list, and has the advantage that you could use a pipe to FINDST in order to avoid the processing of already renamed files if you run the script twice.

not yet tested:

Code: Select all

@echo off
set "var1=2011.01.15 "
for /f "delims=" %%i in ('dir /a-d /b *.txt^|findstr /vrbc:"[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]* "') do ECHO ren "%%~i" "%var1%%%~i"
PAUSE
Remove ECHO and PAUSE if you think the right command lines are displayed.

Note that I changed the position of the quotes in the SET statement in order to avoid that they are part of the value of var1.

Steffen

Redwood
Posts: 3
Joined: 08 Sep 2019 05:20

Re: Cmd For loop is allergic to certain file names

#3 Post by Redwood » 10 Sep 2019 03:05

Thank you for that complex solution.

Actually I found a way to do it the original manner with an if statement seeking if the file already has the "2011.01.15 " string in it.
It involves quite a lot more code than your single 'for /f' statement

But that exotic line of code will be interesting to unravel. I've looked for three days and
nothing explains findstr in detail,
and nowhere is the option /vrbs mentioned
and nowhere have I seen an option for dir of the kind /a-d or /b
and combining echo and ren in one line looks very unusual
and the arguments for ren are really strange.

"changed the position of the quotes in the SET statement" :: something I've never seen before

Yet I still wonder: all three files began with different letters and they were only processed once.
However, a second file with the same initial char as the first caused this non-buffering to appear.

Is this bad luck because of the non-buffering nature of (*.txt) or something insidious in files that start with '0' ?

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Cmd For loop is allergic to certain file names

#4 Post by aGerman » 10 Sep 2019 04:50

Redwood wrote:I've looked for three days
Seriously? Run DIR /? and FINDSTR /? in a CMD window and you'll get the explanation in your native language. Alternatively scroll up and click the Command Index link in the right side bar. /vrbc: is short for /v /r /b /c: btw.
Redwood wrote:and combining echo and ren in one line looks very unusual
aGerman wrote:Remove ECHO and PAUSE if you think the right command lines are displayed.
I can't help you reading my comments. ECHO and PAUSE are only present to check what would happen. No REN command is executed yet in order to protect you from loosing data due to an untested code.
Redwood wrote:Is this bad luck because of the non-buffering nature of (*.txt) or something insidious in files that start with '0' ?
I don't expect that a leading 0 has anything to do with this behavior. Only the fact that 0 comes before the other digits in an alpha sorted list might be the reason why it happens with such file names.

Steffen

Redwood
Posts: 3
Joined: 08 Sep 2019 05:20

Re: Cmd For loop is allergic to certain file names

#5 Post by Redwood » 10 Sep 2019 05:23

Sehr interessant Steffen. Vielen Dank

Eureka!
Posts: 137
Joined: 25 Jul 2019 18:25

Re: Cmd For loop is allergic to certain file names

#6 Post by Eureka! » 10 Sep 2019 05:44

As far as I can tell - don't have the source code of CMD - the for loop starts with the first file (sorted alphabetically by name), then proceeds with the alphabetically next one.
If you rename a file so that it's inserted in the original list, that file will be picked up when it's alphabetically next in line.

You could test that by setting set "var1=0002011.01.15 "
That way the "alphabet pointer" already has passed those new filenames and they will not be parsed again.

Beside using the output of dir /b /a-d like aGerman mentioned (which will create the complete list of files before processing them), you can also avoid confusion by moving the new files out of the way (move "%var2%" "folder\%var3%") adn when the FOR command is done processing your txt files, move them back in place.

But aGerman's way is the normal / de facto way to do this (without the findstr part) ..

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Cmd For loop is allergic to certain file names

#7 Post by aGerman » 10 Sep 2019 06:36

the for loop starts with the first file (sorted alphabetically by name)
That would have been too easy :lol:
viewtopic.php?f=3&t=8636&p=57237

Steffen

Post Reply