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
The following batch file starts a series of programs with a delay after each one.
The problem is to pass a command line with parameters for each program. This requires quotes around the program argument, which are removed when the call is made. This illustrates a few techniques in batch file processing.
Look in the local subroutine :mystart for how an argument in quotes is passed in, and the quotes are removed.
@echo off
rem http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/if.mspx?mfr=true
rem Start programs with delay
rem Wait n seconds
rem n number retries to communicate with the IP address
rem 1000 milliseconds between the retries
rem 127.0.0.1 is the LocalHost
rem start /b (silent) /min (minimized) /belownormal (lower priority)
rem /normal provides a no-op switch to hold the place of argument 1
rem start /normal "Opinions" %SystemRoot%\explorer.exe /e,d:\agar\jobs\opinion
rem ping 127.0.0.1 -n 8 -w 1000 > nul
rem Remove quotes in Batch
rem http://ss64.com/nt/syntax-dequote.html
rem String manipulation in Batch
rem http://www.dostips.com/DtTipsStringManipulation.php
rem ^ line continuation
rem
rem set p="One Two" p has the exact value "One Two" including the quotes
rem set p=%p:~1,-1% Removes the first and last characters
rem set p=%p:"=% Removes all double-quotes
rem set p=%p:cat=mouse% Replaces cat with mouse
rem ping 127.0.0.1 -n 12 -w 1000 > nul
rem 1 2 3 4
@echo on
call :mystart /b/min "Opinions" "%SystemRoot%\explorer.exe /e,d:\agar\jobs\opinion" 8
@echo on
call :mystart /b/min "Notepad++" D:\Prog_D\Notepad++\notepad++.exe 14
@echo on
call :mystart /normal "Firefox" D:\Prog_D\Firefox\firefox.exe 20
@rem call :mystart /b/min "ProcessExplorer" D:\Prog_D\AntiVirus\SysInternals\procexp.exe 8
@echo on
call :mystart /b/min/belownormal "Outlook" D:\Prog_D\MSOffice\OFFICE11\outlook.exe 2
@echo off
goto:eof
:mystart
@echo off
rem %3 is "program-path arguments" with the quotes. We remove the quotes
rem %4 is seconds to wait after starting that program
set p=%3
set p=%p:"=%
start %1 %2 %p%
ping 127.0.0.1 -n %4 -w 1000 > nul
goto:eof
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!)
You can use the %var:x=y%
construction that replaces all x
with y
.
See this example what it can do:
set I="Text in quotes"
rem next line replaces " with blanks
set J=%I:"=%
echo original %I%
rem next line replaces the string 'in' with the string 'without'
echo stripped %J:in=without%
Using the FOR command to strip the surrounding quotation marks is the most efficient way I've found to do this. In the compact form (Example 2) it's a one-liner.
Example 1: The 5-line (commented) solution.
REM Set your string
SET STR=" <output file> (Optional) If specified this is the name of your edited file"
REM Echo your string into the FOR loop
FOR /F "usebackq tokens=*" %%A IN (`ECHO %STR%`) DO (
REM Use the "~" syntax modifier to strip the surrounding quotation marks
ECHO %%~A
)
Example 2: The 1-liner real-world example.
SET STR=" <output file> (Optional) If specified this is the name of your edited file"
FOR /F "usebackq tokens=*" %%A IN (`ECHO %STR%`) DO @ECHO %%~A
I find it interesting that the inner echo ignores the redirection characters '<' and '>'.
If you execute ECHO asdfsd>asdfasd
you will write file out instead of std out.
Hope this helps :)
Edit:
I thought about it and realized there is an even easier (and less hacky) way of accomplishing the same thing. Use the enhanced variable substitution/expansion (see HELP SET
) like this:
SET STR=" <output file> (Optional) If specified this is the name of your edited file"
ECHO %STR:~1,-1%
That will print all but the first and last characters (your quotation marks). I would recommend using SETLOCAL ENABLEDELAYEDEXPANSION
too. If you need to figure out where quotation marks are located in the string you can use FINDSTR to get the character #s.
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%
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.