views:

2115

answers:

5

I have a Windows batch file I'm creating, but I have to ECHO a large complex string, so I'm having to put double quotes on either end. The problem is that the quotes are also being ECHOed to the file I'm writing it to. How to you ECHO a string like that and strip the quotes off?

UPDATE:

I've spent the last two days working on this and finally was able to kludge something together. Richard's answer worked to strip the quotes, but even when I put the ECHO in the subroutine and directly outputed the string, Windows still got hung up on the chars in the string. I'll accept Richard's answer since it answers the question asked.

I ended up using Greg's sed solution, but had to modify it because of sed/windows bugs/features (it didn't help that it came with no documentation). There are a few caveats to using sed in Windows: you have to use double quotes instead of single quotes, you can't escape the double quotes in the string directly, you have to endquote the string, escape using the ^ (so ^") then beqin quote for the next section. Also, someone pointed out that if you pipe input to sed, there's a bug with a pipe being in the string (I didn't get to verify this since in my final solution, I just found a way not to have all quotes in the middle of the string, and just removed all quotes, I never could get the endquote to be removed by itself.) Thanks for all the help.

+1  A: 

Brute force method:

echo "foo <3 bar" | sed -e 's/\(^"\|"$\)//g'

This requires finding a suitable Win32 version of sed, of course.

Greg Hewgill
http://unxutils.sourceforge.net/
KitsuneYMG
Thanks for the direction.
Lance Roberts
A: 

http://unxutils.sourceforge.net/ is a native win32 port of a bunch of GNU utilities including sed, gawk, grep and wget. (sorry that I don't have enough rep to post this as a comment!)

fearoffours
Good idea, I would recommend unxutils over cygwin for most situations.
Greg Hewgill
+2  A: 

This will turn "C:\Program Files\somefile.txt" into C:\Program Files\somefile.txt while still preserving cases such as Height=5'6" and Symbols="!@#

:DeQuote

SET _DeQuoteVar=%1
CALL SET _DeQuoteString=%%!_DeQuoteVar!%%
IF [!_DeQuoteString:~0^,1!]==[^"] (
IF [!_DeQuoteString:~-1!]==[^"] (
SET _DeQuoteString=!_DeQuoteString:~1,-1!
) ELSE (GOTO :EOF)
) ELSE (GOTO :EOF)
SET !_DeQuoteVar!=!_DeQuoteString!
SET _DeQuoteVar=
SET _DeQuoteString=
GOTO :EOF

Example

SetLocal EnableDelayedExpansion
set _MyVariable = "C:\Program Files\ss64\"
CALL :dequote _MyVariable
echo %_MyVariable%
JRL
This could be simplifed by using setlocal and endlocal rather than dereferencing the two local variables. I prefer my solution, though.
Richard A
+2  A: 

The above answer (starting with :DeQuote) assumes delayed environment variable expansion is set to on. From cmd /?:

Delayed environment variable expansion is NOT enabled by default. You can enable or disable delayed environment variable expansion for a particular invocation of CMD.EXE with the /V:ON or /V:OFF switch. You can enable or disable completion for all invocations of CMD.EXE on a machine and/or user logon session by setting either or both of the following REG_DWORD values in the registry using REGEDT32.EXE:

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\DelayedExpansion

    and/or

HKEY_CURRENT_USER\Software\Microsoft\Command Processor\DelayedExpansion

to either 0x1 or 0x0. The user specific setting takes precedence over the machine setting. The command line switches take precedence over the registry settings.

If delayed environment variable expansion is enabled, then the exclamation character can be used to substitute the value of an environment variable at execution time.

james
'The above' here refers to JRL's answer.
Richard A
For a single batch you should probably rather use setlocal enabledelayedexpansion. No need to mess around in the registry or tell users how to call cmd.
Joey
Thanks for the 'setlocal' tip, didn't know that one.
james
+5  A: 

The call command has this functionality built in. To quote the help for call:

 Substitution of batch parameters (%n) has been enhanced.  You can
 now use the following optional syntax:

 %~1         - expands %1 removing any surrounding quotes (")

Here is a primitive example:

@echo off
setlocal
set mystring="this is some quoted text"
echo mystring=%mystring%
call :dequote %mystring%
echo ret=%ret%
endlocal
goto :eof

:dequote
setlocal
rem The tilde in the next line is the really important bit.
set thestring=%~1
endlocal&set ret=%thestring%
goto :eof

Output:

C:\>dequote
mystring="this is some quoted text"
ret=this is some quoted text

I should credit the 'environment variable tunneling' technique (endlocal&set ret=%thestring%) to Tim Hill, 'Windows NT Shell Scripting'. This is the only book I have ever found that addresses batch files with any depth.

Richard A
Great! Is there a similar easy way to strip the quotes when providing a parameter? For the case where we have control only over the calling side, but not the script processing the parameter?
Jens Schauder
Would it be sufficient to wrap your call in your own routine that did the stripping, as above, before doing the call?
Richard A