Variable Substring Assistance - variables

Here's a snippet of my file:
set checkVal=0
:checkforStart
call set checkSub=%%_input:~%checkVal%,1%%
if /i %checkSub% EQU ( goto parenthesisCheck
if /i %checkSub% EQU ' goto noPar
set /a checkVal=%checkVal% + 1
goto checkforStart
:parenthesisCheck
set /a checkVal=%checkVal% + 1
set _startPar=%checkVal%
:checkforEnd
call set checkSub=%%_input:~%checkVal%,1%%
if /i %checkSub% EQU ) goto endParenthesis
if /i %checkSub% EQU ( goto parenthesisCheck
set /a checkVal=%checkVal% + 1
goto checkforEnd
:endParenthesis
set /a _endPar= %checkVal% - %_startPar%
call set parContents=%%_input=:~%_startPar%,%_endPar%%%
echo Parenthesis: %parContents%
:noPar
pause >nul
goto end
The problem I'm having is that when I try to return what was in the parenthesis, it returns:
~1,4
Or something along those lines, instead of the numbers or letters that are supposed to be isolated from the original input.
Thank you for any and all help.
Here is the full file, if you need it: https://www.dropbox.com/s/2lljcy5t7qme0nb/substring%20parenthesis%20finder.txt

That is the value you will get if you attempt to do something like set val=%var:~1,4% when var is undefined. Substring and search/replace operations do not work properly if the variable is undefined - instead they return the instructions after the colon. This is exactly the situation you have because your final assignment has an unwanted = in the expression.
You have:
call set parContents=%%_input=:~%_startPar%,%_endPar%%%
So it is looking to extract a substring from a variable named _input=, which cannot possibly exist - user defined variable names cannot contain =.
Easily fixed by removing the =
call set parContents=%%_input:~%_startPar%,%_endPar%%%

You should instead enable delayed expansion at the start of your script and use ! in place of the surrounding % symbols.
setLocal enableDelayedExpansion
set checkSub=!_input:~%checkVal%,1!
set parContents=!_input=:~%_startPar%,%_endPar%!
Note, you set the checkSub variable twice, it's exactly the same both times, so I didn't include it twice. There are three lines you need to change, and one to add.

....
:endParenthesis
set /a _endPar= %checkVal% - %_startPar%
CALL :inpar %_startPar% %_endPar%
echo Parenthesis: %parContents%
:noPar
GOTO :EOF
:inpar
CALL set parContents=%%_input:~%1,%2%%
GOTO :eof
This worked for me...

It seems that a line that used && that I did not post on here was causing the problem. Sorry for the trouble.

Related

Variable is empty when exporting to file

I'm trying to set a variable every time + 1 with a batch file. So when the batch file opens it calls the file with the var and then redefines it plus 1. But when i open the file and then open count.bat i see this(in count.bat): set backupcount= instead of
set backupcount=1 which it should be (1 can also be 2, 3, 4, 5, enz).
This is the code i'm using:
#echo off
if exist "backup-tool\count.bat" call "backup-tool\count.bat"
if not exist "backup-tool\count.bat" echo set backupcount=0 > "backup-tool\count.bat"
call "backup-tool\count.bat"
if "%backupcount%"=="8" (
echo set backupcount=1 > "backup-tool\count.bat"
) else (
set /a "backupcount=backupcount+=1"
echo set backupcount=%backupcount% > "backup-tool\count.bat"
)
pause >nul
Anyone that knows what i'm doing wrong and tell me how i should do it?
All help is very much appreciated!
This one needs to use setlocal ENABLEDELAYEDEXPANSION, because you work in a block of code where you manipulate that variable and you want to use it right there(not the variable that is out of the block). This should work:
#echo off
setlocal ENABLEDELAYEDEXPANSION
if exist "backup-tool\count.bat" call "backup-tool\count.bat"
if not exist "backup-tool\count.bat" echo set backupcount=0 > "backup-tool\count.bat"
call "backup-tool\count.bat"
if "!backupcount!"=="8" (
echo set backupcount=1 > "backup-tool\count.bat"
) else (
set /a "backupcount=backupcount+=1"
echo set backupcount=!backupcount! > "backup-tool\count.bat"
)
pause >nul
Your original problem is related to Delayed Expansion as other answer said; however, your code is also unnecessarily complex. This is the way I would do it:
#echo off
if exist "backup-tool\count.bat" call "backup-tool\count.bat"
set /A "backupcount=backupcount%%8+1"
echo set "backupcount=%backupcount%" > "backup-tool\count.bat"
The set /A command takes as zero the value of any non-existent variable, so it is not necessary to initialize it with zero when the data file not exists.
If you want a repeating count from 1 to 8 and then reset the counter to 1, you may use the % Modulus operator in a simpler way that don't require an if. Type set /? for further details on %% operator, or see this Wikipedia article.
EDIT: Additional explanations added
The first time the program run the backupcount variable does not exist, so the set /A "backupcount=backupcount%%8+1" expression generate a 1 that is stored in the file. You may also add a set backupcount=0 command before the if just to avoid problems with previous executions of the same Batch file (or add a setlocal command at beginning).
The next time this variable is initialized with 1, so set /A "backupcount=backupcount%%8+1" expression produce a 2. The same happen with next numbers up to 8.
When the variable is initialized with 8 the expression backupcount%%8, that is the remainder when the variable is divided by 8, is zero; so the whole expression produce a 1 again.

How to create nested variables in batch?

I am trying to get nested variables in my batch game i am creating.
I want it so that it will choose a random variable and change it to X, but if it is already chosen, it should go back and choose a different number.
set 1=a
set 2=b
set 3=c
set 4=d
set 5=e
those were the variables, here is the code
setlocal enabledelayedexpansion
:eliminator
set /a eliminate=(%random * 5) / 32767 + 1
if %%eliminate%%==X goto eliminator
echo The letter !!eliminate!! was chosen
timeout 5
set %%eliminate%%=X
goto eliminator
Now, the thing is, when I try to echo it, it writes the name of the variable instead of the value. Also, variables that have already been chosen are being chosen again. Any way I could fix this? Thanks.
try this:
#echo off&setlocal
set "var1=a"
set "var2=b"
set "var3=c"
set "var4=d"
set "var5=e"
:loop
set /a rd=%random%%%5+1
if defined var%rd% call echo %%var%rd%%%
set "var%rd%="
set "var" >nul 2>&1 && goto:loop
..output (may vary):
d
a
c
b
e
Your posted code is missing the closing % around random - it should read %random%.
Your formula for a random number between 1 and 5 is more complicated than need be. I would use:
set /a eliminate=%random% %% 5 + 1
To expand a "nested variable" you need !%eliminate%!
But I would completely rewrite your algorithm. I think the following does what you want:
#echo off
setlocal enableDelayedExpansion
set "chars=abcde"
set charCnt=5
:loop
set /a "pos=%random% %% charCnt, pos2=pos+1, charCnt-=1"
set "letter=!chars:~%pos%,1!"
echo The letter %letter% was chosen
set "chars=!chars:~0,%pos%!!chars:~%pos2%!"
if defined chars goto loop
The script is optimized to always pick a valid unused letter on each iteration.

Removing spaces from a variable in batch

I am writing a file to remove spaces from filenames in a folder and then put the result in a .txt file. I just get a result of "Echo is on." over and over.
This is what I have so far:
#echo ON
SET LOCAL EnableDelayedExpansion
For %%# in (*.*) do (
SET var=%%~n#
Set MyVar=%var%
set MyVar=%MyVar: =%
echo %MyVar%>>text.txt
)
Can someone tell me whats wrong?
Removing all spaces (not just leading and trailing) can be done without using setlocal enabledelayedexpansionwith the following line:
set var=%var: =%
This works by replacing all spaces in the string with the empty string.
Source: DOS - String Manipulation
The reason why you are getting ECHO is on. is because delayed expansion was not used, which caused the value of %var% and %MyVar% to be inserted before the for command is run, and since they were not defined at the start, empty variables were inserted in. When the echo %MyVar%>>text.txt was run, it was interpreted as echo >>text.txt. When echo is run without any arguments, it outputs whether echo is on or off, which is what you get in text.txt.
To fix the problem, you have to do two things:
First, there is something wrong with your second line. There is no space between set and local in setlocal. The second line should be SETLOCAL EnableDelayedExpansion.
Second, to use delayed expansion, you have to replace all %s in each variable with !, like !var! instead of %var%.
End result:
#echo ON
SETLOCAL EnableDelayedExpansion
For %%# in (*.*) do (
SET var=%%~n#
Set MyVar=!var!
set MyVar=!MyVar: =!
echo !MyVar!>>text.txt
)
You actually do not need to use a temporary variable in this case, you can just do SET MyVar=%%~n# and skip to set MyVar=!MyVar: =!.
The wrong thing is you've enabled the variable expansion (you wroted it bad...) and also you are not using it, when you use enabledelayedexpansion you need to write the variable names as this: !Variable! instead of this else: %Variable%
But you don't need to use it with this code:
#echo ON
For %%# in (*) do (
SET "var=%%~n#"
Call Set "MyVar=%%var: =%%"
Call echo %%MyVar%%>>text.txt
)
Run the following batch in the folder holding the files to be renamed
#echo off
setlocal enabledelayedexpansion
for %%j in (*.*) do (
set filename=%%~nj
set filename=!filename=.=_!
set filename=!filename= =_!
if not "!filename!"=="%%~nj" ren "%%j" "!filename!%%~xj"
)
you just need to add the print to txt
The set var=%var: =% did not work for me.
So I tried with success for a number the following code:
set /a var-=1 & set /a var+=1

(Batch) How can I use two variables to refer to another variable in an IF statement?

This is part of the code for a game I'm making.
:south
set "message=You take a step South"
set /a "posY=%posY%+1" //Moves player down one tile
if "%p%posX%%posY%%"=="#" set /a "posY=%posY%-1" //checks if the player has hit a wall. If this is the case, bring him back one tile.
goto renderMap
Assuming %posX%==1 and %posY%==3 I'm trying to get the program to read the IF statement as:
if "p13"=="#" set /a "posY=%posY%-1"
But nothing I've tried seems to work. I was wondering if anyone could show me a proper way to do it.
#ECHO OFF
SETLOCAL
SET p13=#
SET posy=2
SET posx=1
SET /a posy=posy+1
CALL SET destsq=%%p%posx%%posy%%%
IF "%destsq%"=="#" (
ECHO hit wall - ouch!&SET /a posy-=1
) ELSE (ECHO moved south.)
This is probably easiest.
note that what is CALLed is
set destsq=
%% - % escapes the special meaning of %
p
%posx% - evaluated as 1
%posy% - evaluated as 3
%% - % escapes the special meaning of %
so the result is
set destq=%p13%
Note that set/a allows you to do operations without the % and also allows the form set /a var+=something to add %something% to var.
Of course,
set /a var += something
set /a var += %something%
set /a var = var + something
set /a var = %var% + something
set /a var = %var% + %something%
set /a var = var + %something%
all do precisely the same thing. Your choice about which style you use...
see
set /?
from the prompt for docco.
If you are writting a game in Batch, then the speed of your program is important.
There are three ways to use a variable as part of the name of another one: with CALL command, with FOR command, or using Delayed Expansion. CALL is the slowest one and Delayed Expansion the fastest.
Always try to use the shortest way to write any command. The fastest way to increment a variabe is set /A var+=1.
I strongly suggest you to use the standard array notation enclosing the subscripts in square braquets; this form is much clearer. You may read Arrays, linked lists and other data structures in cmd.exe (batch) script for further explanations on this point.
Below is your same code above, but including the previous points:
setlocal EnableDelayedExpansion
:south
set "message=You take a step South"
set /a posY+=1 //Moves player down one tile
if "!p[%posX%][%posY%]!" == "#" set /a posY-=1 //checks if the player has hit a wall. If this is the case, bring him back one tile.
goto renderMap
OK, here is an simple example where you can see, how it works:
#echo off&setlocal enabledelayedexpansion
set "posX=1"
set "posY=3"
set "p13=#"
set "pos=p%posX%%posY%"
if "!%pos%!"=="#" echo "#" found.
.. output is:
"#" found.

Removing double quotes from variables in batch file creates problems with CMD environment

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.
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.
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
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.
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.
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%"
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
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%
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.
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.
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.
set widget="a very useful item"
set widget
widget="a very useful item"
set widget=%widget:"=%"
set widget
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 %
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.
#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.
Azure devops sometimes uses double quoting character (") to specify string. Powershell can use single quote character (') to specify string. Naturally I wanted to have a flexibility to be able to specify parameters however I wish, so same parameter can be used from both - command line - via batch file, and as a powershell script, as any parameter, including empty value.
Quote natural thinking is to write something like this:
build.bat:
#echo off
setlocal enabledelayedexpansion
set args=%*
set args=%args:"='%
echo powershell -executionpolicy bypass "%~dpn0.ps1" %args%
endlocal
But like you can guess - this does not work out of box - if no arguments are provided to batch file so %* == empty string. args expands as no string, and next replacement notices that args is not set - and instead of replacing string - it would append extra "=' garbage to args parameter.
Solution to this was just to add extra space in first assignment.
build.bat:
#echo off
setlocal enabledelayedexpansion
set args=%*
set args=%args:"='%
echo powershell -executionpolicy bypass "%~dpn0.ps1" %args%
endlocal
After this character translation should be correct:
C:\test>build
powershell -executionpolicy bypass "C:\test.ps1"
C:\test>build aa
powershell -executionpolicy bypass "C:\test\build.ps1" aa
C:\test>build "aa"
powershell -executionpolicy bypass "C:\test\build.ps1" 'aa'
C:\test>build 'aa'
powershell -executionpolicy bypass "C:\test\build.ps1" 'aa'