128
votes

Can anybody help with effective and safe way of removing quotes from batch variables?

I have written a batch file which successfully imports a list of parameters %1, %2, %3 etc. and places them into named variables. Some of these parameters contain multiple words, and therefor are enclosed in double quotes.

> "Susie Jo" (%1)  
> "Smith Barnes" (%2)  
> "123 E. Main St." (%3)  

These %variables are next placed in named variables:

> set FirstName=%1  
> set LastName=%2  
> set ShipAddr=%3  

verification of variables is done by echo. > echo.%FirstName%
> echo.%LastName%
> echo.%ShipAddr%

results display as

"Susie Jo"  
"Smith Barnes"  
"123 E. Main St."  

I need to eliminate the included quotes on selected variables. For instance, FirstName and LastName are used elsewhere and must not include quotes.

In a test batch file I was successful at eliminating quotes using the ~tilde character in variables.

> set FirstName=%~1
> set LastName=%~2 

I thought I had the solution, but I soon experienced unusual behavior with execution of batch files. Suddenly CMD is no recognizing long path statments. Normal execution of batch file from full path

> C:\Documents and Settings\Administrator\My Documents\Txt\batchtest\dataout.bat

returns

> 'C:\Documents' is not recognized as an internal or external command....

So it would appear that the addition of the ~tilde character to the in-coming %1 %2...%n variables has caused some change. Possibly some environment variables have been altered?

I also tried clearing quotes from within variable with various attempts using the FOR command. That seems awkward and I have been unable to learn how to accomplish this by creating a list of variable to perform the task:

something like this:

for %%g in (%FirstName% %LastName%) do (
set %%g=%%~g
set %%h=%%~h
set FirstName=%%~g
set LastName=%%h
echo.%FirstName% %LastName%
)

I think I have two issues.

  1. My 'short and sweet' idea of inserting ~tilde in the incoming %1 %2 variables (%~1, etc) seems to have affected some settings and altered how CMD navigates long pathnames.

  2. I'm still in search of a clean and easy way to eliminate quotes from selected named variables.

Any help for those more experienced would be most appreciated. I'm at the end of my skills here... need some guidance please!

edit 12/26/2009 13:36 PST entire batch file:

:: dataout.bat  
:: revision 12/25/2009 add ~tilde to incoming %variables to eliminate embedded "quotation marks.  
:: writes address list using command line parameters  
:: writes data output list for QBooks IIF import  
:: writes Merchant Order data for RUI  
:: sample command line string for testing  
:: listmail[firstname][lastname]["address string"]["city string"][state][zip][Order#][PurchDate][Regname]["FirstName LastName"][TransactionID][PaymentMethod][Total][ProductID][Qty][Price_Each][PackPrep] [Shipping] [CommissionPmt] [Invoice#]  
:: example: dataout Bellewinkle Moose "123 Green Forest Way" "Vancouver" WA 98664 1004968 05/25/2009 "Bellewinkle Moose" "Olive Oyl" 101738 "On Account" 20.67 FK-1P 1 8.95 3.00 1.39 239  
@echo off  
cls  
c:  
cd\  
cd documents and settings\administrator\my documents\txt\batchtest  
echo processing %1 %2  
:VARISET  
:: Convert %n command line parameters to string variables  
set ($FirstName)=%~1  
set ($LastName)=%~2  
set ($BillingAddress1)=%~3  
set ($BillingCity)=%~4  
set ($BillingState)=%~5  
set ($BillingPostal)=%~6  
set ($OrderNumber)=%~7  
set ($Purch_Date)=%~8  
set ($RegistrationName)=%~9  
shift  
set ($TransactionID)=%~9  
shift  
set ($PaymentMethod)=%~9  
shift  
set ($Total)=%~9  
shift
set ($ProductIdentifier)=%~9  
shift  
set ($Quantity)=%~9  
shift  
set ($Price_Each)=%~9  
shift  
set ($Pack_Prep)=%~9  
shift  
set ($Shipping)=%~9  
shift  
set ($ServiceFee)=%~9  
shift  
set ($Discount)=%~9  
shift  
set ($Invoice)=%~9  
shift  
set ($UnitPrice)=%~9  
set _ShipCombName=%($FirstName)% %($LastName)%  
echo ship combo name is %_ShipCombName%  
pause  
:: write string varibables to logfile  
echo FN %($FirstName)% LN %($LastName)% BA %($BillingAddress1)% %($BillingCity)% %($BillingState)% %($BillingPostal)% %($OrderNumber)% %($Purch_Date)% %($RegistrationName)% %($TransactionID)% %($PaymentMethod)% %($Total)% %($ProductIdentifier)% %($Quantity)% %($Price_Each)% %($Pack_Prep)% %($Shipping)% %($ServiceFee)% %($Discount)% %($Invoice)% %($UnitPrice)% %_ShipCombName% >> d_out_log.txt  
:: Assign Account by Service Provider  
IF /i %($PaymentMethod)%==Amazon Receivables SET _QBAcct=Amazon.com  
:: 12-25-2009 added second Amazon pm't method for versatility  
IF /i %($PaymentMethod)%==Amazon SET _QBAcct=Amazon.com  
IF /i %($PaymentMethod)%==MAST SET _QBAcct=Auth/Net  
IF /i %($PaymentMethod)%==MasterCard SET _QBAcct=Auth/Net  
IF /i %($PaymentMethod)%==Visa SET _QBAcct=Auth/Net  
IF /i %($PaymentMethod)%==PayPal SET _QBAcct=PayPalPmts  
IF /i %($PaymentMethod)%==On Account SET _QBAcct=%($RegistrationName)%  
IF /i %($PaymentMethod)%==Mail SET _QBAcct=%($RegistrationName)%  
IF /i %($PaymentMethod)%==AMER SET _QBAcct=Auth/Net  
IF /i %($PaymentMethod)%==DISC SET _QBAcct=Auth/Net  
:: Assign Rep designator based on QBAccount  
IF /i %($PaymentMethod)%==Amazon Receivables SET _Rep=Amazon  
:: 12-25-2009 added second Amazon pm't method for versatility  
IF /i %($PaymentMethod)%==Amazon SET _Rep=Amazon  
IF /i %($PaymentMethod)%==MAST SET _Rep=BlueZap  
IF /i %($PaymentMethod)%==MasterCard SET _Rep=BlueZap  
IF /i %($PaymentMethod)%==Visa SET _Rep=BlueZap  
IF /i %($PaymentMethod)%==PayPal SET _Rep=BlueZap  
IF /i %($PaymentMethod)%==On Account SET _Rep=R B  
IF /i %($PaymentMethod)%==Mail SET _Rep=R B  
IF /i %($PaymentMethod)%==AMER SET _Rep=BlueZap  
IF /i %($PaymentMethod)%==DISC SET _Rep=BlueZap  
:: check for duplicate address data  
findstr /i /s "%_ShipCombName%" addrlist.txt  
echo errorlevel: %errorlevel%  
if errorlevel 1 goto :ADDRWRITE  
if errorlevel 0 goto :ADDRFOUND  
:ADDRWRITE  
echo %_ShipCombName% >> addrlist.txt  
echo %($BillingAddress1)% >> addrlist.txt  
echo %($BillingCity)% %($BillingState)% %($BillingPostal)% >> addrlist.txt  
echo. >> addrlist.txt  
echo Address File Written  
:ADDRFOUND  
echo selected rep is %_Rep%  
echo selected account is: %_QBAcct%  
pause  
:: RUI OUT  
:: write Merchant Order ID & RUI Order ID to RUI  
:: check for duplicate RUI data in writeRUI.txt  
cd..  
cd RegKOut  
find /i "%($OrderNumber)%" writeRUI.txt  
echo errorlevel: %errorlevel%  
if errorlevel 1 goto :RUIWRITE  
if errorlevel 0 goto :IIFWRITE  
:RUIWRITE  
echo %($Invoice)%   %($OrderNumber)% >> writeRUI.txt  
:: end write RUI  
:: IIF OUT  
:IIFWRITE  
:: Check for duplicate invoice data in writeIIF.txt  
find /i "%($OrderNumber)%" writeIIF.txt  
echo errorlevel: %errorlevel%  
if errorlevel 1 goto :HEADWRITE  
if errorlevel 0 goto :LINEWRITE  
:HEADWRITE  
:: write Header, Ship/Handling, discount, Rep & commission data to QB IIF import file  
echo %($OrderNumber)%   %($Purch_Date)% Invoice %($TransactionID)%  %_QBAcct%   Accounts Receivable             %($Total)%  %_Rep% >> writeIIF.txt    
echo                        H/P %($Pack_Prep)%  1   ? >> writeIIF.txt  
echo                        SHP %($Shipping)%   1   ? >> writeIIF.txt  
echo                        DISC    %($Discount)%   1   ? >> writeIIF.txt  
echo                        Comm    %($ServiceFee)% 1   ? >> writeIIF.txt  
:LINEWRITE  
IF /i %($ProductIdentifier)% equ PH-1 goto WRITE_DEFA ELSE goto WRITE_DISC  
echo %($ProductIdentifier)%  
:WRITE_DISC  
::writes discounted prices parsed from custom variable:  
echo                        %($ProductIdentifier)%  %($Price_Each)% %($Quantity)%   ? >> writeIIF.txt  
goto :EOF  
:WRITE_DEFA  
:writes default prices parsed from Product data  
echo                        %($ProductIdentifier)%  %($UnitPrice)%  %($Quantity)%   ? >> writeIIF.txt  
goto :EOF  
:: 3-second delay  
:: TYPE NUL | CHOICE.COM /N /CY /TY,3 >NUL  
:EOF  

11
Could you use PowerShell to do this? I suspect you will get a little more control if you use PowerShell.Robert Harvey
I checked your batch file -- it seems to work fine (after I fixed the line "shift set ($ProductIdentifier)=%~9" -- which, I think, is an artifact of copying-and-pasting it here).atzz
Thank you Robert Harvey; I have been eying PowerShell. I'm not very experience w/ programming.. not sure what the learning curve would be like. I do have some experience w/ batch files, main reason I chose this. I'm intending to compile the batch so it will run faster. Thanks for response.BobB
Thanks atzz: I have since tested this batch file some more and I am reasonably confident that the ~tilde and banishing quotes is unrelated to the CMD problem w/ long pathnames. I worked around that by just setting up a short-name subdirectory close to the root to eliminate long pathnames.BobB
No need to show the full batch file. Please shorten your question.jor

11 Answers

214
votes

You have an extra double quote at the end, which is adding it back to the end of the string (after removing both quotes from the string).

Input:

set widget="a very useful item"
set widget
set widget=%widget:"=%
set widget

Output:

widget="a very useful item"
widget=a very useful item

Note: To replace Double Quotes " with Single Quotes ' do the following:

set widget=%widget:"='%

Note: To replace the word "World" (not case sensitive) with BobB do the following:

set widget="Hello World!"
set widget=%widget:world=BobB%
set widget

Output:

widget="Hello BobB!"

As far as your initial question goes (save the following code to a batch file .cmd or .bat and run):

@ECHO OFF
ECHO %0
SET BathFileAndPath=%~0
ECHO %BathFileAndPath%
ECHO "%BathFileAndPath%"
ECHO %~0
ECHO %0
PAUSE

Output:

"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"
C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd
"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"
C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd
"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"
Press any key to continue . . .

%0 is the Script Name and Path.
%1 is the first command line argument, and so on.

47
votes

Your conclusion (1) sounds wrong. There must be some other factor at play.

The problem of quotes in batch file parameters is normally solved by removing the quotes with %~ and then putting them back manually where appropriate.

E.g.:

set cmd=%~1
set params=%~2 %~3

"%cmd%" %params%

Note the quotes around %cmd%. Without them, path with spaces won't work.

If you could post your entire batch code, maybe more specific answer could be made.

14
votes

I usually just remove all quotes from my variables with:

set var=%var:"=%

And then apply them again wherever I need them e.g.:

echo "%var%"
9
votes

Spent a lot of time trying to do this in a simple way. After looking at FOR loop carefully, I realized I can do this with just one line of code:

FOR /F "delims=" %%I IN (%Quoted%) DO SET Unquoted=%%I

Example:

@ECHO OFF
SET Quoted="Test string"

FOR /F "delims=" %%I IN (%Quoted%) DO SET Unquoted=%%I

ECHO %Quoted%
ECHO %Unquoted%

Output:

"Test string"
Test string
3
votes

This sounds like a simple bug where you are using %~ somewhere where you shouldn't be. The use if %~ doesn't fundamentally change the way batch files work, it just removes quotes from the string in that single situation.

3
votes

I learned from this link, if you are using XP or greater that this will simply work by itself:

SET params = %~1

I could not get any of the other solutions here to work on Windows 7.

To iterate over them, I did this:

FOR %%A IN (%params%) DO (    
   ECHO %%A    
)

Note: You will only get double quotes if you pass in arguments separated by a space typically.

1
votes

The simple tilde syntax works only for removing quotation marks around the command line parameters being passed into the batch files

SET xyz=%~1

Above batch file code will set xyz to whatever value is being passed as first paramter stripping away the leading and trailing quotations (if present).

But, This simple tilde syntax will not work for other variables that were not passed in as parameters

For all other variable, you need to use expanded substitution syntax that requires you to specify leading and lagging characters to be removed. Effectively we are instructing to remove strip away the first and the last character without looking at what it actually is.

@SET SomeFileName="Some Quoted file name"
@echo %SomeFileName% %SomeFileName:~1,-1%

If we wanted to check what the first and last character was actually quotation before removing it, we will need some extra code as follows

@SET VAR="Some Very Long Quoted String"
If aa%VAR:~0,1%%VAR:~-1%aa == aa""aa SET UNQUOTEDVAR=%VAR:~1,-1%
0
votes
  1. set widget="a very useful item"
  2. set widget
  3. widget="a very useful item"
  4. set widget=%widget:"=%"
  5. set widget
  6. set widget=a very useful item"

The trailing quote " in line 4 is adding a quote " to the string. It should be removed. The syntax for line 4 ends with %

0
votes

I thought I had the solution, but I soon experienced unusual behavior with execution of batch files. Suddenly CMD is no recognizing long path statments. Normal execution of batch file from full path

C:\Documents and Settings\Administrator\My Documents\Txt\batchtest\dataout.bat

returns

'C:\Documents' is not recognized as an internal or external command....

There's your whole problem. CMD doesn't understand spaces inside of filenames from the command line, so it thinks you're trying to pass

and Settings\Administrator\My Documents\Txt\batchtest\dataout.bat

as parameters to the

"C:\Documents"

program.

You need to quote it to run a batch file with spaces in the path:

> "C:\Documents and Settings\Administrator\My Documents\Txt\batchtest\dataout.bat"

would have worked.

0
votes
@echo off

Setlocal enabledelayedexpansion

Set 1=%1

Set 1=!1:"=!

Echo !1!

Echo "!1!"

Set 1=

Demonstrates with or without quotes reguardless of whether original parameter has quotes or not.

And if you want to test the existence of a parameter which may or may not be in quotes, put this line before the echos above:

If '%1'=='' goto yoursub

But if checking for existence of a file that may or may not have quotes then it's:

If EXIST "!1!" goto othersub

Note the use of single quotes and double quotes are different.

0
votes

All the answers are complete. But Wanted to add one thing,

set FirstName=%~1

set LastName=%~2

This line should have worked, you needed a small change.

set "FirstName=%~1"

set "LastName=%~2"

Include the complete assignment within quotes. It will remove quotes without an issue. This is a prefered way of assignment which fixes unwanted issues with quotes in arguments.