2

I have a string "-a valueA -b valueB -c valueC", and I want to use bat to split this string by white space and parse the the value "-a" "valueA" "-b" "valueB" "-c" and "valueC" one by one.

Basically, I want to use the for loop to achieve this, however the for loop in bat seems to be far more complicated than I imagine.

I have tried the following codes but obviously it doesn't work.

set TEST_CODE="-a valueA -b valueB -c valueC"
for /f "tokens=* delims= " %%a in (%TEST_CODE%) do (
  echo %%a
)

I'm expecting the output to be

-a    
valueA    
-b   
valueB   
-c  
valueC

I refer to this link, but I'm still confused what exactly is tokens and delims here. Can some bat expert share some ideas on this?

1
  • Is TAB also allowed as a delimiter? and what about ,, ; and =? Commented Nov 19, 2015 at 18:07

2 Answers 2

3

Here's one way to do it. Calls recursive subroutine. The last line is not really needed but I put it there for safety (in case you were to comment out the 'if...goto...' line above it). By way of explanation, you call the subroutine passing the entire string. It strips off the 1st token and calls itself with the remainder of the string until the string is empty.

@echo off
call :GetToken "-a valueA -b valueB -c valueC"
pause
goto :eof

:GetToken
for /f "tokens=1*" %%a in ("%~1") do (
  echo(%%a
  if "%%b"=="" goto :eof
  call :GetToken "%%b"
)
goto :eof
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks:) So what does tokens=1* mean here? Why we use %~1 instead of %1? For the first loop, if %%a represents the -a, then does %%b represents valueA or valueA -b valueB -c valueC?
Tokens 1* means 1 is 1st token and * is rest of the line. %~1 removes quotes... yes, the quotes around it put them back, but that way you don't need to consider whether the string was quoted or not coming in (could have been called from multiple places... some quoted and some not). %%b represents the remainder of the string.
2

Two options for you.

set TEST_CODE=-a valueA -b valueB -c valueC
for /f "tokens=1-6 delims= " %%a in ("%TEST_CODE%") do ( 
    echo %%a
    Echo %%b
    echo %%c
    Echo %%d
    Echo %%e
    Echo %%f
 )

Or

set TEST_CODE=-a valueA -b valueB -c valueC
for  %%a in (%TEST_CODE%) do echo %%a 

And one more option since the answer you picked was a CALL to a function.

call :loop -a valueA -b valueB -c valueC
pause
goto :eof

:loop
IF NOT "%1"=="" (
    echo %~1
    SHIFT
    GOTO loop
)
GOTO :EOF

6 Comments

The first option relies on the assumption that the string always consists of exactly 6 tokens; the second one uses SPACE, TAB, ,, ; and = as delimiters...
@aschipfl, actually the 2nd option does not work in its current form because of the quotes in the SET command. LOL!
The second solution doesn't work for me. It works when I change (%TEST_CODE%) to ("%TEST_CODE%") in the for loop statement, though the -a becomes ""a and valueC becomes valueC"".
@Hackjustu, if you remove the quotes from the SET statement then it works based on your data.
Nice, the key is the quotes... Thanks
|

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.