Executing batch file gives ECHO is off.
The batch file code is present below:
#echo off
setlocal EnableDelayedExpansion
SET a = Hello
SET b = World
SET /A d = 50
SET c = %a% and %b% %d%
echo %c%
endlocal
pause
As MC ND wrote, you have to get rid of spaces before and behind the equality sign. It should be SET a=Hello and not SET a = Hello and so on. This code works as expected:
#echo off
setlocal EnableDelayedExpansion
SET a=Hello
SET b=World
SET /A d=50
SET c=%a% and %b% %d%
echo %c%
endlocal
pause
Further, the lines setlocal EnableDelayedExpansion and endlocal are useless in your code as you never use the delayed expansion (e.g. !a! instead of %a%). Your code is still correct as there is doesn't need delayed expansion.
If you have further questions, please post them as such. Don't expand this post on other questions.
Here are your two, altered codes:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "a=Hello"
SET "b=World"
SET/A "d=50"
SET "c=%a% and %b% %d%"
ECHO %c%
ENDLOCAL
PAUSE
Please check and try them, then read up on the individual commands to learn from your errors.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET/P "pathToJava= **Provide your Response: "
IF /I "%pathToJava%"=="Y" ECHO found
ENDLOCAL
PAUSE
Related
#echo off
#chcp 65001
setlocal enableextensions enabledelayedexpansion
set test=qwert
goto start
:IsStrInStrFunc
setlocal
call set check=%%1:%2=%
echo %check%
endlocal
exit /b
:start
call :IsStrInStrFunc %test%, q
pause
The "check" variable must contain "wert". What's wrong?.......
if you want to set %check% to be "wert"
set check=%%1:%2=%
should be
set check=%test:~1%
For more info check command help set in Command Prompt
Perhaps this example will assist you:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For /F "Delims==" %%G In ('"(Set _cp) 2> NUL"') Do Set "%%G="
For /F Tokens^=* %%G In ('"%SystemRoot%\System32\chcp.com"'
) Do For %%H In (%%G) Do Set "_cp=%%~nH"
If Not %_cp% Equ 65001 (Set "_cpc=TRUE"
"%SystemRoot%\System32\chcp.com" 65001 >NUL)
Set "test=qwert"
GoTo Start
:IsStrInStrFunc
Set "check=%~1"
Echo Before: %check%
SetLocal EnabledelayedExpansion
Set "check=!check:%~2=!"
EndLocal & Echo After: %check%
Exit /B
:Start
Call :IsStrInStrFunc "%test%" "q"
Pause
If Defined _cpc "%SystemRoot%\System32\chcp.com" %_cp% >NUL
GoTo :EOF
To do substring substitution on a variable, you need the variablename, not its value (see set /?), so your parameter in the call can't be %test% (which would pass the string quert), but must be test.
And as you are using delayed expansion anyway, why not using it?
#echo off
#chcp 65001
setlocal enableextensions enabledelayedexpansion
set "test=qwert"
goto start
:IsStrInStrFunc
setlocal
REM call set "check=%%%~1:%~2=%%"
set "check=!%~1:%~2=!"
echo %check%
endlocal
exit /b
:start
call :IsStrInStrFunc test q
PS: you don't need the ~ chars with your simple example, but they don't disturb either. Imagine you want to replace a string, you can simply do that with call :IsStrInStrFunc test "a string" (that's where the ~ are necessary. Good practice to include them anyway (just in case))
I have following code snippet
setlocal enableextensions enabledelayedexpansion
set b=123
for %%f in (.\input\*.mgc) do (
set "b=%%~nf"
echo %b%
)
I am expecting it to output file name with no extension but I always get "123". I concluded it has something with late expansion but not quite sure where the problem comes from. I have also tried with echo !b! but in that situation it outputs only "!b!"
Try replacing %b% with !b! as explained here:
The variable whose expansion should be delayed should be surrounded by exclamation marks instead of percent signs.
setlocal enableextensions enabledelayedexpansion
set b=123
for %%f in (.\input\*.mgc) do (
set "b=%%~nf"
echo !b!
)
I believe in hard evidence. I can't see you execute the code or if you are obfuscating the code at all so here is me executing your code. It works just like I said.
C:\BatchFiles\SO>type testing.bat
#echo off
setlocal enableextensions enabledelayedexpansion
set b=123
for %%f in (.\input\*.mgc) do (
echo %%~nf
set "b=%%~nf"
echo !b!
)
pause
C:\BatchFiles\SO>dir /b .\input\*.mgc
testfile.mgc
C:\BatchFiles\SO>testing.bat
testfile
testfile
Press any key to continue . . .
C:\BatchFiles\SO>
I am trying to double my delayed expansion if that makes any sense. Here is what I want.
set var1=hello
set var2=var1
set var3=var2
echo %!%var3%!%
and then have hello be displayed. This is not my actual code but an example of how I need it to work.
even possible without delayed expansion (although even uglier than rojo's answer) Just a matter of the number of "layers" of parsing and correct escaping the %:
#echo off
set var1=hello
set var2=var1
set var3=var2
call call echo %%%%%%%var3%%%%%%%
Another one without call (faster):
#echo off
setlocal enabledelayedexpansion
set "var1=hello"
set "var2=var1"
set "var3=var2"
for %%v in (!%var3%!) do echo !%%v!
EDIT: Reply to rojo's challenge
Your code have an error in the creation of the variables; all variables contain the string: "var!X!" and the final result is "var!X!X". Below is your code with the variables creation part fixed:
#echo off
setlocal EnableDelayedExpansion
set "var1=hello"
for /L %%I in (2,1,1000) do (
set /a X = %%I - 1
set "var%%I=var!x!"
)
call :follow var1000
goto :EOF
:follow <varname>
setlocal enabledelayedexpansion
set "var=!%~1!"
:follow_loop
if defined !%var%! (
set "var=!%var%!" & goto follow_loop
) else (
echo !%var%!
)
This program correctly show "hello" at end; it takes about 2.51 seconds when run in my computer.
The method is pretty short, so there is not too much chance to improve it; the obvious modification is to change the goto loop by a for (while) one. Here it is:
#echo off
setlocal EnableDelayedExpansion
set "var1=hello"
for /L %%I in (2,1,1000) do (
set /a X = %%I - 1
set "var%%I=var!x!"
)
call :follow var1000
goto :EOF
:follow <varname>
set "var=%~1"
cmd /V:ON /C for /L %%? in () do #for %%v in (^^!var^^!) do #if defined %%v (set "var=^!%%v^!") else echo %%v ^& exit
This code takes about 1.22 seconds to run, that is, just the 48.6% of your method (2 times faster) ;)
You could add a call and surround your first delayed expansion with double percents like this.
#echo off
setlocal enabledelayedexpansion
set "var1=hello"
set "var2=var1"
set "var3=var2"
call echo %%!%var3%!%%
Seems horribly convoluted to me, though. I'd probably rewrite the script to make such trickery not needed if I were me.
Edit: Since there are so many solutions being added here, I'll propose another one. Here's a subroutine that will follow the line of variables from beginning to end, even if it's 1000 levels deep. Just as an academic exercise.
#echo off
setlocal
set "var1=hello"
for /L %%I in (2,1,1000) do (
set /a X = %%I - 1
setlocal enabledelayedexpansion
for %%x in (!X!) do endlocal & set "var%%I=var%%x"
)
call :follow var1000
goto :EOF
:follow <varname>
setlocal enabledelayedexpansion
set "var=!%~1!"
:follow_loop
if defined !%var%! (
set "var=!%var%!" & goto follow_loop
) else (
echo !%var%!
)
And here's another using a batch + JScript hybrid (because the JScript while loop is faster than a batch goto loop).
#if (#CodeSection == #Batch) #then
#echo off
setlocal
set "var1=hello"
for /L %%I in (2,1,1000) do (
set /a X = %%I - 1
setlocal enabledelayedexpansion
for %%x in (!X!) do endlocal & set "var%%I=var%%x"
)
cscript /nologo /e:JScript "%~f0" "var1000"
goto :EOF
#end // end batch / begin JScript hybrid chimera
var env = WSH.CreateObject('Wscript.Shell').Environment('Process'),
itm = WSH.Arguments(0);
while (env(itm)) itm = env(itm);
WSH.Echo(itm);
Your move, Aacini.
This is my batch script:
#echo off
title
setlocal enabledelayedexpansion
:a
set /p a=
!d!
for %%G in (%a%) do (set /a b+=1
if !b! neq 1 (set c=!c!-%%G) else (set c=%%G))
echo wscript.createobject("sapi.spvoice").speak "!c!">a.vbs
start a.vbs
exit
For every time that this program runs, it overwrites the a.vbs file with the new code as variable c. Is it possible to have "wscript.createobject("sapi.spvoice").speak "!c!"" preexisting in a VBScript and simply have batch assign the variable and execute it instead of overwriting and then executing?
With the help of aphoria, I tweaked my scripts to this:
VBScript:
wscript.createobject("sapi.spvoice").speak wscript.arguments(0)
Batch Script:
#echo off
title
setlocal enabledelayedexpansion
set /p a=
for %%G in (!a!) do (set /a b+=1
if !b! neq 1 (set c=!c!-%%G) else (set c=%%G))
cscript //nologo b.vbs !c!
exit
May I suggest you another solution?
JScript language is similar to VBScript, but have an advantage in this case: the JScript code can be placed inside the Batch file itself via a very simple trick. This way, it is not necessary to create a separated file with the JScript code:
#if (#CodeSection == #Batch) #then
:: Previous line is:
:: - in Batch: a valid IF command that does nothing
:: - in JScript: a conditional compilation IF statement that is false
:: so the following code is omitted until the next atSign-end
#echo off
title
setlocal enabledelayedexpansion
set /p a=
for %%G in (!a!) do (set /a b+=1
if !b! neq 1 (set c=!c!-%%G) else (set c=%%G))
rem Execute this Batch file as a JScript one:
cscript //nologo //E:JScript "%~F0" !c!
exit
#end
WScript.CreateObject("sapi.spvoice").Speak(WScript.Arguments(0));
In this case the original VBScript code is so simple that the JScript translation is immediate; just note that the uppercase letters are needed in JScript. However, I am not entirely sure that spvoice execute the same in JScript than in VBScript; you must do a test...
Create a script file SpeakNumber.vbs (call it whatever you want).
Put this inside it:
Set args = Wscript.Arguments
WScript.CreateObject("sapi.spvoice").Speak args(0)
Then, change your batch file like this:
#echo off
title
setlocal enabledelayedexpansion
:a
set /p a=
!d!
for %%G in (%a%) do (set /a b+=1
if !b! neq 1 (set c=!c!-%%G) else (set c=%%G))
START SpeakNumber.vbs !c!
exit
This is my batch script:
#echo off title setlocal enabledelayedexpansion :a set /p a= !d!
for %%G in (%a%)
do (set /a b+=1
if !b! neq 1
(set c=!c!-%%G)
else
(set c=%%G))
echo wscript.createobject("sapi.spvoice").speak "!c!">a.vbs
start a.vbs
exit
You dont have use a hybrid as you can embed the vbs file inside the batch file.
#echo off
set /p "Voice= Enter what you would like to say : "
echo dim speechobject >> sapi.vbs
echo set speechobject=createobject("sapi.spvoice") >> sapi.vbs
echo speechobject.speak "%Voice%" >> sapi.vbs
start sapi.vbs
timeout /t 1 /nobreak
del sapi.vbs
I have a complex string I'm trying to parse. I have a short subroutine to fine the index of two specific characters, and I need the string in between. So the question is:
How do I use variables inside string manipulation of another variable?
Here's some sample code:
#ECHO off
set start=2
set end=5
set str=Hello World
echo %str:~2,5%
echo %str:~%start%,%end%%
How do I get the second echo to display what the first echo displays? (right now second echo is just showing what I want, it'll crash as is)
#ECHO off
set start=2
set end=5
set str=Hello World
setlocal enableDelayedExpansion
echo %str:~2,5%
echo !str:~%start%,%end%!
endlocal
or (the worst way)
#ECHO off
set start=2
set end=5
set str=Hello World
echo %str:~2,5%
call echo %%str:~%start%,%end%%%
or (can be used if start and end definition and the substringing are all in brackets context)
#ECHO off
set start=2
set end=5
set str=Hello World
echo %str:~2,5%
setlocal enableDelayedExpansion
for /f "tokens=1,2" %%a in ("%start% %end%") do echo !str:~%%a,%%b!
endlocal
or (also a bad way)
#ECHO off
set start=2
set end=5
set str=Hello World
call :substr "%str%" %start% %end%
goto :eof
:substr
setlocal enableDelayedExpansion
set "_str=%~1"
echo !_str:~%2,%3!
rem without delayedExpansion
rem call echo %%_str:~%2,%3%%
endlocal
goto :eof
CALL echo %%str:~%start%,%end%%%
in place of your version. No need for enabledelayedexpansion