Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
davep
- Posts: 24
- Joined: 29 May 2008 14:03
- Location: Nauf Kakalak
#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: 2461
- Joined: 12 Feb 2011 21:02
- Location: United States (east coast)
#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
#3
Post
by davep » 03 Jun 2015 12:16
Excellent! Thank you!
-
Ben Mar
- Posts: 22
- Joined: 03 May 2015 10:51
#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: 1913
- Joined: 06 Dec 2011 22:15
- Location: México City, México
-
Contact:
#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: 231
- Joined: 01 Oct 2012 13:32
- Location: Ireland
-
Contact:
#6
Post
by Sponge Belly » 10 Aug 2015 13:22
Hello All!
Sorry I’m late to the discussion, as usual.
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: 2461
- Joined: 12 Feb 2011 21:02
- Location: United States (east coast)
#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.
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
#8
Post
by davep » 10 Aug 2015 18:08
Wonderful solution, Dave. I'll try it out asap. Thank you!