Reputation: 2543
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
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
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
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