10

I have the following string:

MyProject/Architecture=32bit,BuildType=Debug,OS=winpc

I would like to be able to grab the values 32bit, Debug, and winpc and store them in variables named Architecture, BuildType, and OS to reference later in the batch script. I'm normally a Unix guy so this is new territory for me. Any help would be greatly appreciated!

user869525
  • 769
  • 2
  • 12
  • 21

3 Answers3

31

This should do it:

FOR /F "tokens=1-6 delims==," %%I IN ("MyProject/Architecture=32bit,BuildType=Debug,OS=winpc") DO (
    ECHO I %%I, J %%J, K %%K, L %%L, M %%M, N %%N
)
REM output is: I MyProject/Architecture, J 32bit, K BuildType, L Debug, M OS, N winpc

The batch FOR loop is a pretty interesting piece of machinery. Type FOR /? in a console for a description of some of the crazy stuff it can do.

D.Shawley
  • 58,213
  • 10
  • 98
  • 113
9

Here is an interesting solution that doesn't care how many or what order the name=value pairs are specified. The trick is to replace each comma with a linefeed character so that FOR /F will iterate each name=value pair. This should work as long as there is only one / in the string.

@echo off
setlocal enableDelayedExpansion
set "str=MyProject/Architecture=32bit,BuildType=Debug,OS=winpc"

::Eliminate the leading project info
set "str=%str:*/=%"

::Define a variable containing a LineFeed character
set LF=^


::The above 2 empty lines are critical - do not remove

::Parse and set the values
for %%A in ("!LF!") do (
  for /f "eol== tokens=1* delims==" %%B in ("!str:,=%%~A!") do set "%%B=%%C"
)

::Display the values
echo Architecture=%Architecture%
echo BuildType=%BuildType%
echo OS=%OS%

With a bit more code it can selectively parse out only name=value pairs that we are interested in. It also initializes the variables to undefined in case the variable is missing from the string.

@echo off
setlocal enableDelayedExpansion
set "str=MyProject/Architecture=32bit,BuildType=Debug,OS=winpc"

::Eliminate the leading project info
set "str=%str:*/=%"

::Define a variable containing a LineFeed character
set LF=^


::The above 2 empty lines are critical - do not remove

::Define the variables we are interested in
set "vars= Architecture BuildType OS "

::Clear any existing values
for %%A in (%vars%) do set "%%A="

::Parse and conditionally set the values
for %%A in ("!LF!") do (
  for /f "eol== tokens=1* delims==" %%B in ("!str:,=%%~A!") do (
    if !vars: %%B ! neq !vars! set "%%B=%%C"
  )
)

::Display the values
for %%A in (%vars%) do echo %%A=!%%A!
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • This looks amazing, and incomprehensible. I'd love more detail on "%str=%str:*/=%", and "!str:,=%%~A!". The first one doesn't make sense why there's an '=' at the end, the second has a mystery ~ in it. – Kieveli Sep 14 '16 at 14:38
  • Works for smaller sets of data, but I'm querying a list of 24k items now, and the assignment of a command output appears to be longer than the maximum allowed length for batch file variables. – Kieveli Sep 15 '16 at 13:06
  • 1
    @Kieveli - Yes, environment variables used by CMD.EXE are limited to maximum length of about 8191 bytes long. – dbenham Sep 15 '16 at 16:23
  • looking for a windows batch guru? go retire early :) – grenix Mar 16 '17 at 13:36
  • Amazing: If you believe one empty line would be enough try this: echo 1!LF!2!LF!3!LF!4!LF!\n ::The above 2 empty lines are critical - do not remove\n echo 1!LF!2!LF!3!LF!4!LF!\n Can anyone explain? – grenix Mar 16 '17 at 13:40
4

Try the following:

@ECHO OFF

SET Var=MyProject/Architecture=32bit,BuildType=Debug,OS=winpc

FOR /F "tokens=1,2,3 delims=," %%A IN ("%Var%") DO (
    FOR /F "tokens=1,2 delims==" %%D IN ("%%A") DO (
        SET Architecture=%%E
    )
    FOR /F "tokens=1,2 delims==" %%D IN ("%%B") DO (
        SET BuildType=%%E
    )
    FOR /F "tokens=1,2 delims==" %%D IN ("%%C") DO (
        SET OS=%%E
    )
)

ECHO %Architecture%
ECHO %BuildType%
ECHO %OS%

PAUSE
LittleBobbyTables - Au Revoir
  • 32,008
  • 25
  • 109
  • 114
  • 4
    Just for fun, consider replacing your three inner `FOR` loops with the single line `SET %%A & SET %%B & SET %%C`. Great name BTW. – D.Shawley Sep 27 '12 at 21:11