Reputation: 3037
Say I have a string such as foo:bar:baz, is it possible to loop through this string? It looked like you could tokenize lines of a file but the following will only echo 'foo' once.
for /f "tokens=1,2* delims=:" %%x in ("%%j") do echo %%x
Upvotes: 18
Views: 37196
Reputation: 3421
This will parse the string into variables accessable outside of the loop (;
setlocal enabledelayedexpansion
set your_string="whatever:you:want"
for /f "tokens=1,2,3 delims=:" %%a in ('echo !your_string!') do (
set first_sub_string=%%a
set second_sub_string=%%b
set third_sub_string=%%c
)
echo Congrats. !your_string! was parsed as !first_sub_string!, !second_sub_string!, !third_sub_string!
Upvotes: 3
Reputation: 130889
Aacini beat me to my first solution. It can be improved by adding quotes so that the string can contain spaces and special characters and still give the correct result.
set "str=foo bar:biz bang:this & that"
for %%S in ("%str::=" "%") do echo %%~S
The solution has limitations:
The second solution has bizarre syntax, but the concept is fairly straight forward. FOR /F with "string" will break on linefeed characters - each line will be processesed as its own string. The trick is to replace the :
delimiter with a linefeed character. Note that the blank line in the solution below is a critical part of the tricky replacement. Also, the following line must start with the !
which terminates the delayed variable expansion. There should not be any leading spaces.
The other thing to worry about is the pesky FOR /F "EOL" option. We don't want to skip any values that start with the EOL character which is ;
by default. Since we have eliminated the string delimiter :
, we can safely use that as the EOL.
Finally, we need to use delayed expansion, but !
will be corrupted during %%S expansion if we don't first disable delayed expansion within the loop.
set "str=foo bar:biz bang:this & that "^& the other thing!":;How does this work?"
setlocal enableDelayedExpansion
set ^"str=!str::=^
!"
for /f "eol=: delims=" %%S in ("!str!") do (
if "!!"=="" endlocal
echo %%S
)
I believe this technique can handle just about anything you throw at it.
jeb was the first to show me how to work with line feeds within batch, and especially how to use this technique. It may even be posted already somewhere else on SO.
Upvotes: 11
Reputation: 29349
it does as expected, it tokenizes it to %%x
%%y
%%z
. So instead of just processing %%x
, you might...
for /f "tokens=* delims=:" %%x in ("foo:bar:baz") do (
echo %%x
echo %%y
echo %%z
)
or if you don't know in advance how many items you got, you may...
@echo off
set string=foo:bar:baz
:again
for /f "tokens=1* delims=:" %%x in ("%string%") do (
echo %%x
set string=%%y
)
if not .%string%==. goto again
echo done
Upvotes: 3
Reputation: 67216
set string=foo:bar:baz
for %%x in (%string::= %) do echo %%x
FOR value delimiters may be space, comma, semicolon and equal-sign. You may directly process a string if the elements are delimited with any of these characters. If not, just change the delimiter for one of these character (as I did above).
set string=foo bar,baz;one=two
for %%x in (%string%) do echo %%x
Upvotes: 21