I'm having a bit of trouble with a batch script which needs to parse a value out of an config file into a variable.
Suitably anonymised, the relevant line of the file looks like
<?define ProductShortName="Foo" ?>
I want to set a variable to Foo
. The string ProductShortName
is unique enough to get the line with findstr
, but then I have to extract the value. The correct approach seems to be for /F
, but all of the following give errors:
for /F "delims=^" usebackq" %%G in (`findstr /L "ProductShortName" "%~dp0Installer\Branding.wxi"`)
for /F "delims="" usebackq" %%G in (`findstr /L "ProductShortName" "%~dp0Installer\Branding.wxi"`)
for /F "delims=\" usebackq" %%G in (`findstr /L "ProductShortName" "%~dp0Installer\Branding.wxi"`)
for /F 'delims=^" usebackq' %%G in (`findstr /L "ProductShortName" "%~dp0Installer\Branding.wxi"`)
for /F 'delims=" usebackq' %%G in (`findstr /L "ProductShortName" "%~dp0Installer\Branding.wxi"`)
for /F "delims=" usebackq" %%G in (`findstr /L "ProductShortName" "%~dp0Installer\Branding.wxi"`)
mostly along the lines of
usebackq" %G in (`findstr /L "ProductShortName" "C:\foo\bar\Installer\Branding.wxi"`) was unexpected at this time.
What's the correct way of escaping it to split the string on "
?
You can use the double quotation mark as a delimiter with syntax like:
FOR /F delims^=^"^ tokens^=2 %G IN ('echo I "want" a "pony"') DO @ECHO %G
When run on the command line, using tokens^=2
should give you want
, and 4 tokens gets you a pony.
Applying the technique to your original question, this should work in your batch file:
FOR /F delims^=^"^ tokens^=2 %%G IN ('FINDSTR /L "ProductShortName" "data.txt"')
Details
I'm no expert on quirks of the command line parser, but it may help to think of the usual "delims=blah tokens=blah"
as a single, combined argument passed to FOR. The caret escaping trick in delims^=blah^ tokens^=blah
bypasses the need for enclosing quotes while still treating the sequence as a single argument. I've used a bit of creative analogy here, and the effect isn't universal across the shell. E.g. you can't do dir C:^\Program^ Files
(which makes sense since ^
is a valid filename character).
Test Cases
With sufficient escaping, you can quickly check your original sample on the command line:
FOR /F delims^=^"^ tokens^=2 %G IN ('echo ^^^<?define ProductShortName="Foo" ?^^^>') DO @ECHO %G
Others playing with this may want to create a file testcases.txt:
blah blah "red"
blah "green" blah
How about a "white" "unicorn"?
and run something like:
FOR /F delims^=^"^ tokens^=2 %G IN (testcases.txt) DO @ECHO %G
to check results for a variety of inputs. In this case it should yield:
red
green
white
One last example:
FOR /F delims^=^"^ tokens^=2 %G IN ('FINDSTR /L "unicorn" "testcases.txt"') ^
DO @ECHO The unicorn is %G.
Finally, note my testing for this was done on Windows Server 2003.