Page 1 of 1

For Loop Question

Posted: 04 Dec 2014 20:05
by ALbino
Hey guys,

I have a little loop where I search for all .txt files and pull a number from them before doing a calculation on it and renaming the file.

The original filenames look like:

Filename~0001.txt

I am then pulling 0001, performing a calculation and renaming them to:

Filename-0001__0_mins_1_secs.txt

This works perfectly fine, but the annoyance I'm running into is that in a folder that already contains renamed files it still tries to process them even though there is no ~ in them. Here's a snippet of my code:

Code: Select all

for /F "tokens=1,2 delims=~" %%G in ('dir /b *.txt') do (

   set FilenameWithoutNumber=%%G

   set NumberWithExtension=%%H

   rem Right here is a bunch of calculations which I have removed

   ren !FilenameWithoutNumber!~!NumberWithExtension! !FilenameWithoutNumber!-!FileSpecificNumber!__!TotalTime!.txt

   echo Renamed !FilenameWithoutNumber!~!NumberWithExtension! to !FilenameWithoutNumber!-!FileSpecificNumber!__!TotalTime!.txt
)



Which correctly renames the files that have ~0001 but gives an error on the ones that have already been renamed to -0001__0_mins_1_secs.txt.

Here's the output:

Code: Select all

Missing operator.
The syntax of the command is incorrect.
Renamed Filename-0001__1_mins_0_secs.txt~ to Filename-0001__1_mins_0_secs.txt-~0,4__208_mins_20_secs
.txt


This isn't a huge deal as the previously renamed files aren't actually affected (since the rename filename input ends up being wrong), but it would be better if they were just ignored all together. Without doing anything complicated, is there some simple way I'm missing that I can modify my For Loop to skip processing the ones that don't contains a ~? Thanks in advance!

Re: For Loop Question

Posted: 04 Dec 2014 20:41
by Squashman
change your file mask.
Dir /b *~*.txt

Re: For Loop Question

Posted: 04 Dec 2014 21:09
by ALbino
Squashman wrote:change your file mask.
Dir /b *~*.txt


That's the first thing I tried, but it didn't work. Here's is my line:

Code: Select all

for /F "tokens=1,2 delims=~" %%G in ('dir /b *~*.txt') do (


Here's the output from a directory with one renamed file and one that has yet to be renamed...

Input files:
Filename~0001.txt
Filename-0002__0_mins_2_secs.txt

Result:

Code: Select all

Renamed Filename~0001.txt to Filename-0001__0_mins_1_secs.txt
Missing operator.
The syntax of the command is incorrect.
Renamed Filename-0002__0_mins_2_secs.txt~ to Filename-0002__0_mins_2_secs.txt-~0
,4__208_mins_20_secs.txt


Am I missing something?

Re: For Loop Question

Posted: 04 Dec 2014 21:23
by ALbino
I think maybe the tilde (~) is the problem. Just opening a command prompt and using any other character seems to work, but when I use *~* this is what happens:

Code: Select all

C:\test\textfiles>dir /b *~*.txt
Filename~0001.txt
Filename-0002__0_mins_2_secs.txt


But if I just search for *_* or *-* or *2* it's fine:

Code: Select all

C:\test\textfiles>dir /b *_*.txt
Filename-0002__0_mins_2_secs.txt


Is ~ an illegal character of some sort in this instance?

Re: For Loop Question

Posted: 04 Dec 2014 22:34
by ALbino
Just an update: I've switched from using ~'s to using +'s and dir /b *+*.txt works fine, so I'm going to go with that. Though I'm still not sure why ~'s don't work.

Re: For Loop Question

Posted: 05 Dec 2014 07:46
by Squashman
Yes. I forgot the tilde is used with short file names. You should really look at picking a different character to name the initial file names.
Do this at the cmd prompt and you will see why the tilde is a bad idea.

Code: Select all

dir /a-d /x

Re: For Loop Question

Posted: 05 Dec 2014 09:38
by Yury
*

Re: For Loop Question

Posted: 05 Dec 2014 10:11
by Squashman
Cool. What other modifiers did they add to Windows 8 and above?
I have always wanted them to change the DIR /Q option to a modifier.

Re: For Loop Question

Posted: 05 Dec 2014 11:30
by dbenham
Yes, the short file names can wreak havoc on the unwary :twisted:

You can fix your code fairly easily and still preserve the ~. You just need to modify your FOR /F to use FINDSTR to filter out the unwanted files:

Code: Select all

for /F "tokens=1,2 delims=~" %%G in ('dir /b *.txt^|findstr /xi "[^~]*~[0-9][0-9]*\.txt"') do ...


This is a good application for my JREN.BAT - the full solution is a one liner :!: :D

Code: Select all

@echo off
call jren "^(.*?)~(\d+)(\.txt)$" "$1+'-'+$2+'__'+Math.floor($2/60)+'_mins_'+($2%%60)+'_secs'+$3" /j


Dave Benham

Re: For Loop Question

Posted: 05 Dec 2014 13:33
by Squashman
Dave, I knew you would have the solution. I remember you helping me with a short file name problem a few months back. Wasn't quite the same issue but we did pipe it to findstr to resolve the problem.
viewtopic.php?f=3&t=5802

Re: For Loop Question

Posted: 05 Dec 2014 16:35
by ALbino
Ah, short filenames. That makes sense. Thanks for the feedback and the help guys. Much appreciated!