18

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

4 Answers 4

21
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
Sign up to request clarification or add additional context in comments.

5 Comments

Could you explain the delimeter syntax above a little bit more please?
@WonkotheSane: I am afraid I don't understand what you refer by "delimiter syntax". The %string::= % is just a string replacement that changes semicolons by spaces. The FOR value delimiters are comma, semicolon and equal-sign, besides space and TAB, as described here
Do you mean changes colons by spaces? That's where I'm getting lost.
@WonkotheSane: You can read about string replacement at this page
From that page- %variable:StrToFind=NewStr% So, if I were to read your second line, I'm reading it as "%string:" is "look at the variable string", then for the StrToFind you have ":" which I am thinking means "look for the value colon (:)", and "= %" means "and replace it with a space."
11

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:

  • No * or ? can appear in the string
  • Problems can arise if the string already contains quotes ("), especially if there are special characters as well

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.

2 Comments

Can you tell me why are you escaping the first quotation mark like ^" at the string replacement? and why do you not escape the second one?
Ah damn, stupid me! I got it know: an unescaped " would make the ^ to be kept literally... strangely I found that out not by testing the code but by attending to something completely different since I posted the comment; quite nerdy, is it not? ;-)
3

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

1 Comment

hmm, I guess what I want is to be able to loop through tokens like I can loop through lines in a file. A nice way of doing this: stackoverflow.com/questions/6966558/batch-file-for-f-tokens
3

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!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.