Using Variable As For-Loop Token Value

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
davep
Posts: 24
Joined: 29 May 2008 14:03
Location: Nauf Kakalak

Using Variable As For-Loop Token Value

#1 Post by davep » 03 Jun 2015 11:31

Hello batchers!

I'm trying to split a path string, and I've run into an issue where using %var% as a token value works as expected, but !var! does not:

Code: Select all

@echo off
setlocal enableextensions
setlocal enabledelayedexpansion

set "file=E:\temp\TEST\123458--text_text1\filename.mp4"
set tokenNum=4

echo.
for /f "tokens=%tokenNum% delims=\-" %%b in ("%file%") do (
   @echo.%tokenNum% = %%b
)

echo.
echo.and now with exclamation points
echo.

for /l %%n in (1,1,5) do (
   set "tokenNum=%%n"
   for /f "tokens=!tokenNum! delims=\-" %%b in ("%file%") do (
      @echo.!tokenNum! = %%b)   
)

echo.
pause


The resulting output is:

Code: Select all

C:\Users\davep\Desktop>scratch.bat

4 = 123458

and now with exclamation points

!tokenNum! delims=\-" was unexpected at this time.
!tokenNum! delims=\-" was unexpected at this time.
!tokenNum! delims=\-" was unexpected at this time.
!tokenNum! delims=\-" was unexpected at this time.
!tokenNum! delims=\-" was unexpected at this time.

Press any key to continue . . .


This is a severely reduced version of my script just to show the issue. There are a few other steps that mandate the setting of tokenNum within the loop. Long story short, I never know how deep the file is within the path, so I need to count the number of \ so I can choose the right token value to always return 123458. I can get that number fairly easily, but planting it into a for-loop using exclamation points is breaking the script.

Thank you for your time,

Dave

dbenham
Expert
Posts: 2288
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Using Variable As For-Loop Token Value

#2 Post by dbenham » 03 Jun 2015 12:05

The FOR /F options are parsed prior to FOR variable expansion and delayed expansion. So you cannot use either as part of FOR /F options.

One solution is to CALL out to a subroutine, passing the values as parameters so that you can use %1 instead.

Code: Select all

for /l %%n in (1,1,5) do call :parse %%n
exit /b

:parse
for /f "tokens=%1 delims=\-" %%b in ("%file%") do echo %1 = %%b
exit /b


Dave Benham

davep
Posts: 24
Joined: 29 May 2008 14:03
Location: Nauf Kakalak

Re: Using Variable As For-Loop Token Value

#3 Post by davep » 03 Jun 2015 12:16

Excellent! Thank you!

Ben Mar
Posts: 22
Joined: 03 May 2015 10:51

Re: Using Variable As For-Loop Token Value

#4 Post by Ben Mar » 03 Jun 2015 14:14

Another solution:

Code: Select all

@echo off
setlocal enableextensions
setlocal enabledelayedexpansion

set "file=E:\temp\TEST\123458--text_text1\filename.mp4"

set count=1
:forLoop
for /f "tokens=%count% delims=\-" %%a in ("%file%") do (
   echo !count! = %%a
   set /a count+=1)
   if !count! lss 7 goto forLoop
)

Aacini
Expert
Posts: 1617
Joined: 06 Dec 2011 22:15
Location: México City, México

Re: Using Variable As For-Loop Token Value

#5 Post by Aacini » 03 Jun 2015 14:57

... and another solution, the classical array method that allows to store each part and later process they as you want:

Code: Select all

@echo off
setlocal enabledelayedexpansion

set "file=E:\temp\TEST\123458--text_text1\filename.mp4"

rem Separate the path in tokens
set "file2=%file:-=" "%"
set i=0
for %%a in ("%file2:\=" "%") do if %%a neq "" (
   set /A i+=1
   set "token[!i!]=%%~a"
)

rem Show elements of "token" array
for /l %%n in (1,1,6) do (
   set "tokenNum=%%n"
   for /f %%b in ("!tokenNum!") do (
      @echo.!tokenNum! = !token[%%b]!
   )   
)

Or in a simplified form, if just one part is needed:

Code: Select all

@echo off
setlocal enabledelayedexpansion

set "file=E:\temp\TEST\123458--text_text1\filename.mp4"

set tokenNum=4

set "file2=%file:-=" "%"
set i=0
for %%a in ("%file2:\=" "%") do if %%a neq "" (
   set /A i+=1
   if !i! equ %tokenNum% echo %tokenNum% = %%~a
)


Antonio

Sponge Belly
Posts: 196
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: Using Variable As For-Loop Token Value

#6 Post by Sponge Belly » 10 Aug 2015 13:22

Hello All!

Sorry I’m late to the discussion, as usual. :oops:

But my solution takes advantage of the popping the CALL stack technique Siberia-Man told us about on June 7th:

Code: Select all

@echo off & setlocal enableextensions disabledelayedexpansion
set ^"str=^"  ^&^^    ^"^^^&^"^& !^^!^^^^! %%  %%OS%%^"
set "str=%str:"=""%"

call :awhile 0
set /a count-=1
echo(count is: %count%

endlocal & goto :eof

:awhile
set /a count=%1+1
(for /f eol^=^ tokens^=%count% %%A in ("%str%") do rem awhile
) && ((goto) 2>nul & call :awhile %count%)
exit /b 0


No non-terminating for /l loops, no backward-jumping gotos. Pretty nifty… if I say so myself. ;)

- SB

dbenham
Expert
Posts: 2288
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Using Variable As For-Loop Token Value

#7 Post by dbenham » 10 Aug 2015 14:06

Most of the answers have ignored the request to use a variable in FOR /F options, and instead have offered alternative ways to count the number of path nodes.

But if the goal is to simply extract the leading number from the parent folder of a file (given the full path of the file), then all you need do is use .. to get the parent folder :!: There is no need to know the number of nodes. :roll:

Code: Select all

@echo off
setlocal
set "file=E:\temp\TEST\123458--text_text1\filename.mp4"
for %%F in ("%file%\..") do for /f "delims=-" %%N in ("%%~nF") do echo %%N


Dave Benham

davep
Posts: 24
Joined: 29 May 2008 14:03
Location: Nauf Kakalak

Re: Using Variable As For-Loop Token Value

#8 Post by davep » 10 Aug 2015 18:08

Wonderful solution, Dave. I'll try it out asap. Thank you!

Post Reply