AndyC
AndyC

Reputation: 2543

Windows batch file - splitting a string to set variables

I feel like I'm going around in circles with FOR loop options.

I'm trying to take a string (output of a command) and split it on commas, then use each value to SET, e.g.

String: USER=Andy,IP=1.2.3.4,HOSTNAME=foobar,PORT=1234

So I want to split on comma and then literally use that variable in SET. I don't know ahead of time how many many variables there will be.

I've tried things like:

FOR %%L IN (%MYSTRING%) DO ECHO %%L

but that splits on the equals sign too so I end up with

USER
Andy
IP
1.2.3.4

etc

I just want to be able to do the following so I can SET USER=Andy etc, something like:

FOR %%L IN (%MYSTRING%) DO SET %%L

What option or flags am I missing?

Upvotes: 4

Views: 30390

Answers (3)

lakrits
lakrits

Reputation: 11

Dunno if anyone is interested in this, but I couldn't find any info on how to do this anywhere, so... I was wrestling with how to do something similar in a subroutine and have all the set variables available to the scope where the subroutine was called from. But if you try to use endlocal & set in the for loop everything will get fudged up after the first iteration.

The solution is to create a string with & set "A=B" prepended to it for every loop iteration. Starting with an empty string before loop starts, and with A and B changed to whatever variablename and value was found in the delimetered string for that iteration of the loop. Remember to escape the double quotes though or weirdness will probably happen.

Then after the for loop is done you should end up with a string like this &set "A=B"&set "C=D"&set "E=F" stored in some variable. Then just run endlocal %returnstring% which should expand to setlocal &set "A=B"&set "C=D"&set "E=F" then exit /b and all those variables should be available after the subroutine has finished.

This is what my code looks like within the for loop (set "return=" was done before loop):

set "return=!return!&set ^"!name!=!value!^""

And after the loop, the last lines of the subroutine:

endlocal %return%
exit /b

Notice there is no & between setlocal and %return% since there is a & prepended to the string. Also I don't think endlocal !return! would work due to how delayed expansion works.

Upvotes: 0

Aacini
Aacini

Reputation: 67216

The default delimiters for elements in plain FOR command (no /F option) are spaces, tab, commas, semicolons and equal signs, and there is no way to modify that, so you may use FOR /F command to solve this problem this way:

@echo off 

set MYSTRING=USER=Andy,IP=1.2.3.4,HOSTNAME=foobar,PORT=1234

:nextVar
   for /F "tokens=1* delims=," %%a in ("%MYSTRING%") do (
      set %%a
      set MYSTRING=%%b
   )
if defined MYSTRING goto nextVar
echo USER=%USER%, IP=%IP%, HOSTNAME=%HOSTNAME%, PORT=%PORT%

Another way to solve this problem is first taking the variable name and then executing the assignment for each pair of values in a regular FOR command:

setlocal EnableDelayedExpansion

set MYSTRING=USER=Andy,IP=1.2.3.4,HOSTNAME=foobar,PORT=1234

set varName=
for %%a in (%MYSTRING%) do (
   if not defined varName (
      set varName=%%a
   ) else (
      set !varName!=%%a
      set varName=
   )
)
echo USER=%USER%, IP=%IP%, HOSTNAME=%HOSTNAME%, PORT=%PORT%

EDIT 2023/01/20: New method added

I know this is a very old question. However, I can't resist the temptation to post a new very interesting method to solve this old problem:

@echo off 

set MYSTRING=USER=Andy,IP=1.2.3.4,HOSTNAME=foobar,PORT=1234

set "%MYSTRING:,=" & set "%"

echo USER=%USER%, IP=%IP%, HOSTNAME=%HOSTNAME%, PORT=%PORT%

If you want to know where the magic is, remove the @echo off line, execute the program and carefully review the screen...

Upvotes: 16

Marco Montel
Marco Montel

Reputation: 581

In case your input is something like HOSTNAME:PORT and you need to split into separate variables then you can use this

@echo off
set SERVER_HOST_PORT=10.0.2.15:8080


set SERVER_HOST_PORT=%SERVER_HOST_PORT::=,%

for /F "tokens=1* delims=," %%a in ("%SERVER_HOST_PORT%") do (
   set SERVER_HOST=%%a
   set SERVER_PORT=%%b
)

echo SERVER_HOST=%SERVER_HOST%
echo SERVER_PORT=%SERVER_PORT%

Upvotes: 1

Related Questions