How to add quotes to string in a batch script [duplicate] - batch-file

This question already has answers here:
Batch PATH with Quotes
(4 answers)
Closed 9 years ago.
Basically I have a variable that has a string in it that is the path to an uninstall program. Sometimes when the variable gets returned it'll return something like
"C:/path to uninstall file/uninstall.exe"
While other times it may return
MsiExec.exe /I{regkeyhere}
Both of those are fine, it's when something like this get's returned
C:/path to uninstall file/uninstall.exe
Where there are no quotes in a file path that causes the call function to fail. Is there anyway to check if the variable begins with a C: and if it does add a quote to the beginning and the end of the string? If it begins with anything other than C: then it doesn't matter, its only if it has a file path with spaces in it that it breaks down. I've tried a couple different string replaces, but for some reason it always breaks down.

Use a caret to escape the quotes:
if "%variable:~0,2%"=="C:" set variable=^"%variable%^"
EDIT: I realised there would be an error if quotes already existed, so this code will create a test variable (with quotes removed) to test the variable first. This code also will not add quotes if there are no spaces.
If it starts with C:, ( If there are spaces don't add quotes, else, add quotes ).
set test=%uninstallStr:"=%
if "%test:~0,2%"=="C:" (
if "%test: =%"=="%test%" (
set uninstallStr=%test%
) else (
set uninstallStr=^"%test%^"
)
)
EDIT 2: I realised there would be more problems with poison characters like < and >, so this code will escape those poison characters first before processing..
set ^"uninstallStr=^"C:\Program Files ^<x86^>\Price Check by AOL\uninstall.exe^"^"
echo %uninstallStr%
set "test=%uninstallStr:"=%"
set "test=%test:<=^<%"
set "test=%test:>=^>%"
if "%test:~0,2%"=="C:" (
if "%test: =%"=="%test%" (
set uninstallStr=%test%
) else (
set uninstallStr=^"%test%^"
)
)
echo %uninstallStr%
pause

Related

String compare with batch file [duplicate]

This question already has an answer here:
Variables are not behaving as expected
(1 answer)
Closed 3 years ago.
A very simple batch file. I'm trying to search for file extensions that are not .txt. There will be one .txt, but the rest will be like .txt_20190607.
for %%I in (\\01mtsdv130\Myapp\Log\*.*) do (
set var1=%%~xI
echo %var1
if %var1%==".txt" (
echo Matches
) else (
echo does not match
)
)
I have files in that folder both .txt and those with the extra date info in the extension. What do I have wrong?
There are two problems in the code.
The first one is that %-based expansion of normal variables is rather "static", in that it happens the first time code is parsed/executed and is fixed since then. That means that in iterations of the loop after the first, the result of %var1% will not change. You'd have to use !var1! (along with setting EnableDelayedExpansion) to get the behaviour you want.
An easier alternative is to get rid of var1 altogether and just use %%~xI.
The other problem is that CMD treats quotes (almost) as any other character. Most notably, the strings a and "a" are not considered equal. Therefore, the if should look like this:
if "%%~xI"==".txt" (

Set variable to %%f [duplicate]

This question already has answers here:
Defining and using a variable in batch file
(4 answers)
Closed 4 years ago.
I set a variable in cmd with the set command, and tried to echo it.
Here is an example:
C:\Users\Logan>set var = text
C:\Users\Logan>set var
var = text
C:\Users\Logan>echo %var%
%var%
C:\Users\Logan>
Is there a way to force the cmd to echo the variable and not the raw text?
Assigning a value/string to an environment variable
It is best to use following syntax with command extensions enabled to define or modify an environment variable:
set "var=text"
The command is set and the parameter is "variable=value".
The parameter string can be enclosed in double quotes as on all commands as long as command extensions are enabled as by default.
If the double quotes are not used around variable=value, command set interprets everything to end of line after the first equal sign including not visible spaces and horizontal tabs at end of line as string value to assign to the variable.
The name of the variable starts with first non whitespace character (after double quote if used) and ends left to first equal sign. The value assigned to the variable starts right of first equal sign and ends at end of line or last double quote.
set VAR = TEXT
The command line above creates an environment variable with name VARSpace and assigns the string SpaceTEXT to this variable.
The usage of
set var="text"
is often not correct as this results in assigning to variable var the text with the quotes included and all trailing spaces and tabs. Referencing now var on another code line with surrounding quotes often results in an error message as the variable holds itself the text already with quotes. For more details see the answer on How to set environment variables with spaces?
Example:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "var=text"
set "var = text"
set "var1=and more text"
set var2="and more text"
set var3="text with 1 trailing space"
set var
echo var3=%var3%^<- Do you see the trailing space?
echo/
set UnwantedSpaceVar=Hello
echo %UnwantedSpaceVar%! ^<- Where does the space come from?
echo/
echo There is a trailing space after Hello in this code snippet.
echo/
set "TrailingSpacesIgnored=Hi"
echo %TrailingSpacesIgnored%! ^<- The 3 trailing spaces above are ignored.
echo/
endlocal
pause
Running this small batch code results in the output:
var=text
var = text
var1=and more text
var2="and more text"
var3="text with 1 trailing space"
var3="text with 1 trailing space" <- Do you see the trailing space?
Hello ! <- Where does the space come from?
There is a trailing space after Hello in this code snippet.
Hi! <- The 3 trailing spaces above are ignored.
Enclosing variable=value in quotes can be done even if the text itself contains 1 or more double quotes.
set "Quote=""
This line defines the variable Quote with the value ". Command set interprets everything after first equal sign left to last double quote as value to assign to variable with name between the first quote and first equal sign.
Note: A string value with " inside and next & or && or || can be even on usage of set "variable=value" misinterpreted and so result in unexpected behavior as it can be seen on running a batch file with following two lines:
#echo off
set "Variable=Value with one double quote in the middle" & echo Oh, there is something wrong here!"
Value with one double quote in the middle" & echo Oh, there is something wrong here! is the string to assign to the environment variable, but assigned to the variable is just Value with one double quote in the middle and the rest of the line after " in the middle and after & interpreted as conditional operator and not literally is interpreted as additional command to execute by cmd.exe. The same problem exists with && or || after a " with 0 or more spaces/tabs between. This problem is not caused by command set. It is caused by Windows command processor which splits the line up into a command line with set and one more command line with echo with conditional execution of the echo command line.
Variable assignment with disabled command extensions
The command syntax set "variable=value" cannot be used if the command extensions are disabled with setlocal DisableExtensions in the batch file (or in Windows registry which is very uncommon and never seen by me on any Windows computer). A syntax error would be the result on execution of the batch file.
It is only possible to use set variable=value with command extensions disabled whereby the value can contain also double quotes and care must be taken on trailing spaces/tabs as they are also assigned to the environment variable.
Run in a command prompt window cmd /? and setlocal /? for more information about command extensions and which commands are affected by command extensions. Note: The output list of affected commands misses exit as described in answers on Where does GOTO :EOF return to?
Variable assignment via arithmetic expression
Using command set with option /A changes completely the parsing of second argument, i.e. the string after set /A. With option /A as first argument the second string is interpreted as arithmetic expression and being therefore processed completely different than on assigning a string value to an environment variable. Environment variables are always of type string and never of type integer.
The usage of option /A requires enabled command extensions as otherwise the command set ignores the rest of the line completely without any error message.
It is in most cases not recommended to just assign a number to an environment variable using an arithmetic expression, i.e. using set /A var=1. set "var=1" or just set var=1 (and no trailing whitespaces) are a little bit faster because environment variables are always of type string.
In an arithmetic expression whitespaces are interpreted as delimiters for variable names, numbers and operators. For that reason the command line set /A var = 1 does not define a variable with name VARSpace with the string Space1 as set var = 1 does. set /A var = 1 defines a variable with name VAR with string value 1 after converting 1 from string (batch file contains 1 as character with hexadecimal code value 31) to integer with value 1 and back to a string with the two values 0x31 and 0x00 (string terminating null).
Variable assignment via a prompt
Also using command set with option /P changes the parsing of the
string after variable name and equal sign. The string after the variable name and the equal sign is interpreted as prompt text to output and not as string to assign to the environment variable.
The environment variable gets assigned the string entered by prompted user (or redirected from a file or command/application), or in case of user does not enter anything before pressing RETURN or ENTER, keeps its current value respectively is still undefined if not defined before the prompt.
The usage of option /P requires enabled command extensions as otherwise the command set ignores the rest of the line completely without any error message.
Most used syntax for prompting a user for a string is:
set /P var="Please enter something: "
The command set removes in this case automatically the double quotes around the prompt text before printing to handle STDOUT (console window if not redirected).
But working is also:
set /P "var=Please enter something: "
Please read this answer for more details about prompt text parsing and how to output a prompt text with surrounding double quotes.
You need to remove whitespace before and after =:
set "var=text"
echo %var%
text

Two sets of double quotes batch file error

Why does the following batch script fail?
Is it because there are 2 sets of double quotes?
How do I get this to work??
SET INCOME-CODE="test (bob, bob2)"
IF "%INCOME-CODE%"=="NULL" (
SET APCINVOICE=%APCINVOICE%,
) ELSE (
SET APCINVOICE=%APCINVOICE%%INCOME-CODE%,
)
Two things.
First, your variable INCOME-CODE actually has quotes in it. Try this short demonstration:
#echo off
set TEST1="this is a string with spaces"
set "TEST2=this is a string with spaces"
echo %TEST1%
echo %TEST2%
Second, you are comparing to the literal string "NULL". There is no NULL value in batch. Please see this post for more details: What is the proper way to test if variable is empty in a batch file... What you probably want to do is compare to an empty string or use one of the methods in the question above if you're working with something more complex.
IF "%INCOME-CODE%"=="" ( ... )

How to use a directory that contains round brackets in a batch file

I have a batch file in which the 2 first lines read:
set DIRwhereRUN=C:\UNIVERSITY\testSTABLEunstable(WITHrandomBED)
PUSHD %DIRwhereRUN%
but the batch does not work.
If I create a directory named testSTABLEunstable_WITHrandomBED and copy my stuff there everything works smoothly. Is there a way to make it work with the brackets? I don't want to rename for at least 2 reasons.
It's very difficult - and misleading - to isolate two lines as you have. There's nothing wrong with those two lines.
The difficulty that you are having is with "block" statements like
IF ... (something
something
somethinginvolving DIRWHERERUN
)
This is because batch substitutes the value of any %var% with its the-current value before executing the command(s) and hence misinterprets the ) in %Dirwhererun% as the closing-parenthesis of the IF (or ELSE or FOR.)
The way to overcome this is to "escape" %dirwhererun%'s ) (ie. temporarily suspend its special meaning) - this is done with the caret ^ - which itself is a special character (with the special meaning "the following character is just a character, not a special character".)
So - how to do this?
Here's a demonstration:
#ECHO OFF
setlocal
set "DIRwhereRUN=U:\UNIVERSITY\testSTABLEunstable(WITHrandomBED^)"
SET dir
set DIRwhereRUN=U:\THISWILLBEWRONG(WITHrandomBED^)
SET dir
set DIRwhereRUN=U:\UNIVERSITY\testSTABLEunstable(WITHrandomBED^^)
SET dir
set DIRwhereRUN=U:\UNIVERSITY\testSTABLEunstable(WITHrandomBED)
SET dir
MD %DIRwhereRUN%
PUSHD "%DIRwhereRUN%"
DIR
POPD
SET dirwhererun=%dirwhererun:)=^^)%
SET dir
(Note that I use U: as a temporary drive. I'm creating the directory using your original SET deliberately to show that it's not the SET or normal operations that are causing the problem)
Note that where the set uses quotes around the parameters, the value is applied literally. This form is often used to ensure that stray trailing spaces in lines are not included in the value set into the variable.
Note that the ^ seems ineffectual in the next set - because all it is doing is escaping the ) - and ) is NOT a special character in an ordinary SET
With the third version, the caret is included - but only one, because ^ escapes ^ and ) is an ordinary character.
Then we do all of the operations using the ) unadorned. Obviously attempting to re-create a directory is going to cause an error - but it's because the directory already exists, not because there's anything wrong with the command itself.
As demonstrated, the directory will be listed, so the PUSHD works correctly.
Finally, there's a method of setting a variable dynamically - possibly better set into another variable-name. This is useful where the variable may be read from a file or input from a user - that is, not specified literally.
Well - not quite finally. Two further quirks: First, % is not escaped by ^ but by %, and second, ECHO( appears to be the most flexible form of ECHO (where the character immediately following ECHO, normally space, but may be a number of others) - and doesn't participate in the statement-blocking mechanism.
( and ) are special characters to the shell, so you need to escape them. Cmd.exe's escape character is ^. So you can do the following:
set DIRWHERERUN=C:\UNIVERSITY\testSTABLEunstable^(WITHrandomBED^)
Bill
Use double quotes.
set "DIRwhereRUN=C:\UNIVERSITY\testSTABLEunstable(WITHrandomBED)"
PUSHD "%DIRwhereRUN%"

How do I set an environment variable to a value with spaces in a batch file?

I don't know how to describe exactly what I'm trying to do but here's an example batch file that demonstrates what I can't figure out.:
I've got a batch file. Inside that batch file I'm trying to create a directory:
Set CopyFrom = %~dp0
if Exist "%ProgramFiles(x86)" (
Set TargetDir = %ProgramFiles(x86)%\My Directory Name has spaces
)
md %TargetDir%\NewSubFolder
copy %CopyFrom%\SourceFile.zip %TargetDir%\NewSubFolder
My batch file is failing on line 4 Set TargetDir =... with:
\My was unexpected at this time
I'm assuming this is because I have spaces in my path name. I thought I could just wrap my variable with quotes:
Set TargetDir = "%ProgramFiles(x86)%\My Directory Name has spaces"
But then when I get to the line that creates the directory it fails because %TargetDir% is now wrapped in quotes. md "%TargetDir%"\NewSubFolder
Can this be fixed or should I just write a VBScript to sort things out?
Just put your expression in quotes like this:
C:\>Set "TargetDir=%ProgramFiles%\My Directory Name has spaces"
C:\>echo %TargetDir%
C:\Program Files\My Directory Name has spaces
Note: It will expand the variable within the quotes, and if it too has spaces, it will need to be quoted.
Now you can quote it to perform your operation:
md "%TargetDir%\NewSubFolder"
The problem in question here are not the spaces as others suggested, but rather the closing parenthesis in the environment variable ProgramFiles(x86) This causes the parser to think that the block ends prematurely (shameless self-promotion).
Quotes do help in this case because they make the parser jump over the whole quoted part and rightly assume the following parenthesis to be the actual closing one. but the fix might be much easier than that:
if Exist "%ProgramFiles(x86)%" Set TargetDir=%ProgramFiles(x86)%\My Directory Name has spaces
Why use a parenthesized block at all if all you do it put exactly one command into it?
set itself doesn't need any quotes, except when its arguments contain special characters like <, >, |, & which the shell itself aready handles. It isn't a panacea, though which makes handling user input or file contents correctly a pain at times.
Also, please never ever put spaces around the = in a set command. This will cause an environment variable to be created with its name ending in a space and its contents starting with a space. This was partially corrected in Windows 7 by silently creating both the variable with the space at the end and one without:
> set foo = bar
> set foo
foo=bar
foo = bar
But in previous versions of Windows this didn't happen so just never use spaces around the = unless you know this is what you want :-)

Resources