Delayed expansion with string manipulation and variable - batch-file

The following command in a batch file returns the error
"1!==1 was unexpected at this time"
#echo off
setlocal enabledelayedexpansion
set num1=0
set/p "pass=>"
:start
set/a num1=%num1%+1
set/a num2=%num1%-1
if !pass:~%num2%,1!==1 set pass%num1%=1& goto start
The last line repeats once for every one digit number, the ==1 being replaced.

Since you don't say what you are entering as "pass", we're guessing.
Your if command should be
if "!pass:~%num2%,1!"=="1" set pass%num1%=1& goto start
which ensures that both sides of the operator == sontain non-empty strings.
That won't help your logic flaws, but it will cure the error report. You don't say clearly what you are trying to achieve, so beyond that...who knows?

You should use a temporary variable for your if command, like this:
#echo off
setlocal enableDelayedExpansion
set num1=0
set/p "pass=>"
:start
set/a num1=%num1%+1
set/a num2=%num1%-1
set "temppass=!pass:~%num2%,1!"
if [%temppass%]==[1] echo set pass%num1%=1& goto start
pause
The pause and the echo in the if are for debug-purposes and should probably be removed

Related

Formatting generated numbers in a .bat file

Forgive me if there is a simple answer to this, I'm new to all of this.
The below .bat script generates a list of numbers depending on how many numbers you want.
However what I would like is to format the numbers it generate.
For example, if I input 20, instead of it coming out 1, 2, 3 etc. I would like it to come out as 001, 002... 020.
Is this possible? Am I missing something obvious?
Many Thanks.
#echo off
setlocal EnableExtensions
:start
cls
set /p loopcount= How Many Users?:
set "x="0"
:loop
set /a "x+=1"
echo %x%
set /a loopcount=loopcount-1
if %loopcount%==0 goto exitloop
goto loop
:exitloop
pause
goto start
just implementing SomethingDark's suggestion (and a minor change in the logic of the loop):
set /p "loopcount= How Many Users?: "
set "x=1000"
:loop
set /a x+=1
echo %x:~-3%
set /a loopcount-=1
if %loopcount% gtr 0 goto :loop
echo loop finished.
(btw: your set "x="0" has a quote too much (probably a typo)
Here's a quick example batch file which uses powershell for your leading zeroes.
I have used a for loop as the looping mechanism.
#Echo Off
SetLocal EnableExtensions
:AskNum
Set "num=1"
Set /P "num=how many users?"
Set num | findstr.exe /RX "^num=[123456789][0123456789]*$" 1>NUL || GoTo AskNum
For /F %%G In ('powershell.exe "1..%num% | %% ToString User000"') Do Echo %%G
Pause
This script will not continue unless the end user inputs an integer, without a leading 0, and which is a minimum value of 1. Here you can modify the Echo command in Do to an alternative, for example net.exe User %%G /Add, or if you wish, to a parenthesized sequence of commands. In each case %%G will contain the returned string with the incremented three digits.This version prepends each three digit number sequence with an additional string, (User), but that can simply be deleted or replaced if/as required.
#ECHO OFF
SETLOCAL enabledelayedexpansion
SET /p "lastnum= How many numbers? "
SET /a lastnum+=1000
FOR /L %%e IN (1001,1,%lastnum%) DO SET /a num=%%e&ECHO !num:~-3!
GOTO :EOF
No need for complication

Batch file crashes after if statement

I'm trying to make a linux like terminal with batch. I don't know what's wrong with the code.
It crashes after
Set "word[!i!]=%cmd: ="&Set /A i+=1&Set "word[!i!]=%"
echo %word[1]%
if "%word[1]%==ls" dir.
Here's my code:
#Echo on
pushd C:\
Set "cmd="
For /F "Delims==" %%A In ('Set word[') Do Set "%%A="
set "UserAccount=%username%"
cls
:Loop
SetLocal EnableDelayedExpansion
Set /P "cmd=%UserAccount%#%UserAccount%~%cd%$ "
If Not Defined cmd EndLocal EnableDelayedExpansion & GoTo Loop
Set "i=1"
Set "word[!i!]=%cmd: ="&Set /A i+=1&Set "word[!i!]=%"
echo %word[1]%
if "%word[1]%==ls" dir
if "%word[1]%==cd" goto cd
if "%word[1]%==cd .." cd..
if "%word[1]%==cd ." cd.
GoTo Loop
:cd
if Not Defined %word[2]% echo %cd% & GoTo Loop
cd %word[2]%
EndLocal EnableDelayedExpansion
goto Loop
Probably you've coded
Set "word[!i!]=%cmd: ="&Set /A i+=1&Set "word[!i!]=%"
where you intended
Set "word[!i!]=%cmd: =%"&Set /A i+=1&Set "word[!i!]="
You'd then need to fix
if "%word[1]%==ls" dir
to
if /i "%word[1]%"=="ls" dir
(where the /i has been inserted to make the comparison case-insensitive)
I'd also avoid using cmd as a variable-name since cmd.exe is the command-processor itself.
Also, be aware that setlocal establishes a copy of the current environment which is released by an endlocal. As your code currently stands your setlocals are not balanced by endlocals` so you have an ever-accumulating nested environment arrangement - and the nesting level is limited.
As well as completely overhauling your SetLocal/EndLocal expressions...
Change:
if "%word[1]%==ls"
to
If /I "%word[1]%"=="ls"
Also change:
if "%word[1]%==cd"
to
If /I "%word[1]%"=="cd"
These two are not possible because each are two words, where %word[1]% is just cd
if "%word[1]%==cd .."
if "%word[1]%==cd ."
Also change:
if Not Defined %word[2]%
to
If Not Defined word[2]
Also, I told you when I gave you the code for setting your words, that it depended on your sentences. If you are expecting that entering commands and having the special characters and syntax recognized as individual words with that code then your likely to be disappointed.

ECHO is off error while executing batch file

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

How to use set and if statements in batch files

So i'm trying to make a small batch program with some sets and ifs, seems easy enough right? Apparently, you can't use "set" and "if" like this.
#echo off
setlocal enabledelayedexpansion
cls
set variableTrue EQU 1
Then continue the code and later in the program do this.
If %variableTrue% EQU 1 goto next
Please note I've tried it with exclamation marks as well.
With the exclamation marks, it's like it completely ignores the statement, even if it's true it will continue as usual. With the percentage signs, it says very quickly before crashing
"1" was not expected at this time.
Or something like that, like I said it barely stayed for half a second.
I always thought you could do it like this as long as there are no conflicting variables.
:start
#echo off
setlocal enabledelayedexpansion
title test
color a
cls
:favnum
cls
echo What is your favorite number?
set /p fn=Favorite Number
If "!fn!" NEQ 13 goto thanks
If "!fn!" EQU 13 goto setvar
:setvar
set "coolestNum==1"
:thanks
cls
If "!coolestNum!"== 1 goto cool
echo Thanks
pause
goto :eof
:cool
echo cool
pause
goto :eof
That doesn't give an error, it just ignores the statement and keeps going as usual.
UPDATE:
After fixing errors this still doesn't work.
When I use exclamation marks it ignores the line, and when I use percentage signs it says:
"
"1 was not expected at this time"
One set of problems is your IF statements. For example, If "!coolestNum!"== 1 goto cool. The quotes are included in the comparison.
You need to be symmetric - either include quotes on both sides
If "!coolestNum!" == "1" goto cool
or neither:
If !coolestNum! == 1 goto cool
The same problem exists with If "!fn!" EQU 13 goto setvar, as well as the line before it.
The other problem you have is set "coolestNum==1" has an extra, unwanted =. The second = becomes part of the value. You only want two equal signs with IF comparisons.
Here is corrected code:
:start
#echo off
setlocal enabledelayedexpansion
title test
color a
cls
:favnum
cls
echo What is your favorite number?
set /p fn=Favorite Number
If "!fn!" NEQ "13" goto thanks
If "!fn!" EQU "13" goto setvar
:setvar
set "coolestNum=1"
:thanks
set coolest
cls
If "!coolestNum!"=="1" goto cool
echo Thanks
pause
goto :eof
:cool
echo cool
pause
goto :eof
But your logic is needlessly convoluted. The following produces the exact same result.
:start
#echo off
setlocal enabledelayedexpansion
title test
color a
cls
echo What is your favorite number?
set /p fn=Favorite Number
if !fn! equ 13 (
set "coolestNum=1"
echo cool
) else echo Thanks
pause
exit /b
Use
set variableTrue=1
rather than
set variableTrue EQU 1
This batch script:
#echo off
setlocal enabledelayedexpansion
cls
set variableTrue=1
echo A
if %variableTrue% EQU 1 goto next
echo B
goto :EOF
:next
echo C
outputs
A
C

Passing exclamation marks as parameters in batch subroutine call

Thanks to this community I have finally learned how to escape exlamation marks for immediate use in a batch delayedExpansion block.
(use two escape carets not just one, awesome)
But I can't seem to find or figure out how to pass the contents of a variable containing an exclamation mark as parameter to a batch subroutine.
example:
#echo off
setLocal EnableDelayedExpansion
set variable=Hello^^!
echo "!variable!"
call :subroutine "!variable:^^!=^^!!"
pause
exit
:subroutine
echo "%~1"
exit/b
Output:
"Hello!"
"Hello"
Press any key to continue . . .
I want the second "Hello" to include an exclamation mark.
I have tried various permutations of substring replacement on line 5 to no avail.
help
You need a different way for the variable replacing, and much more carets.
#echo off
setLocal EnableDelayedExpansion
set variable=Hello^^!
echo "!variable!"
call :subroutine %variable:!=^^^^^^^^^^!%
exit /b
:subroutine
echo %~1
exit /b
Or with quotes:
call :subroutine "%variable:!=^^^!%"
In your function you need to expand %1 without any quotes, as the number of carets are always odd in a CALL parameter.
But at all it's a bad idea to try such things.
I agree with Aacini, that you should use pass by reference instead.
This is the only way to handle any possible content.
#echo off
setLocal EnableDelayedExpansion
set variable=Hello^^!
echo "!variable!"
call :subroutine variable
exit /b
:subroutine
echo !%1!
exit /b
Maybe the problem is not how to pass the data to the subroutine, but how to get the data inside it
#echo off
setlocal enabledelayedexpansion
set "var=Hello^!"
setlocal disabledelayedexpansion
echo %var%
call :echo1 %var%
call :echo2 var
endlocal
setlocal enabledelayedexpansion
echo !var!
call :echo1 !var!
call :echo2 var
endlocal
endlocal
exit /b
:echo1
setlocal disabledelayedexpansion
echo %~1
endlocal
goto :eof
:echo2
setlocal enabledelayedexpansion
echo !%~1!
endlocal
goto :eof

Resources