The problem is that my set tap=c:\ca\sf\1st 2nd... etc. isn't working at all.
The echo shows nothing, the set isn't putting the path in the variable for some reason.
I got all ifs right, is there another problem?
setlocal enabledelayedexpansion
if NEWYORK == %region% (
set tap=C:\ny
CALL :process %1 %2 %tap% %cl%
GOTO :EOF
)
if California == %region% (
if '%3'=='sanfrancisco' (
set cl=c:\ca\sf\cl
if '%2'=='1st' set tap=c:\ca\sf\1st
if '%2'=='2nd' set tap=c:\ca\sf\2nd
if '%2'=='3rd' set tap=c:\ca\sf\3rd
if '%2'=='4th' set tap=c:\ca\sf\4th
if '%2'=='5th' set tap=c:\ca\sf\5th
echo %tap%, echo %cl%,
pause
CALL :process %1 %2 %tap% %cl%
GOTO :EOF
)
if '%3' == 'LosAngeles' (
set tap=c:\ca\la
set cl=c:\ca\la\cl
echo %tap%, %cl%
pause
CALL :process %1 %2 %tap% %cl%
GOTO :EOF
)
set tap=c:\USA
set cl=c:\usa\cl
echo %tap%, %cl%
pause
CALL :process %1 %2 %tap% %cl%
GOTO :EOF ) else (
echo faiiiiiiiiiillllllllll
pause
GOTO :END)
endlocal
GOTO :EOF
You missed the first SET command. The line
tap=C:\ny
must be
set tap=C:\ny
When you use a variable that is modified inside an IF or FOR its value must be expanded with !var! and not with %var%; otherwise the expanded value is the value the variable had BEFORE enter the IF or FOR (this is the objective of EnableDelayedExpansion). For example:
set var=Old value
if 1 == 1 (
set var=New value
echo With percent: %var%. With exclamation: !var!
)
Previous segment show: With percent: Old value. With exclamation: New value
An additional comment:
Although if NEWYORK == %region% is the same as if %region% == NEWYORK when it is executed, the second one is customary and clearer from programmers point of view.
EDIT
I slightly modified your code. Take a look at it:
setlocal enabledelayedexpansion
if /I %region% == NEWYORK (
set tap=C:\ny
REM cl IS NOT DEFINED HERE, BUT USED IN NEXT LINE
CALL :process %1 %2 !tap! !cl!
GOTO :EOF
)
if /I %region% == California (
if /I '%3' == 'sanfrancisco' (
set cl=c:\ca\sf\cl
set tap=c:\ca\sf\%2
echo !tap!, !cl!
pause
CALL :process %1 %2 !tap! !cl!
GOTO :EOF
)
if /I '%3' == 'LosAngeles' (
set tap=c:\ca\la
set cl=c:\ca\la\cl
echo !tap!, !cl!
pause
CALL :process %1 %2 !tap! !cl!
GOTO :EOF
)
set tap=c:\USA
set cl=c:\usa\cl
echo !tap!, !cl!
pause
CALL :process %1 %2 !tap! !cl!
GOTO :EOF
) else (
echo faiiiiiiiiiillllllllll
pause
GOTO :END
)
endlocal
GOTO :EOF
Related
I have a batch function and I need to return a value from it. Following is the script:
#echo off
call :Mode mode1
echo mode is %mode1%
:Mode
setlocal enabledelayedexpansion
set count=0
for /f "tokens=*" %%x in (map.txt) do (
set /a count+=1
set var[!count!]=%%x
)
for /f "tokens=2 delims=: " %%A in ("%var[2]%") Do (
set mode=OPEN
)
IF %mode%==OPEN (
echo coming into open
set %1=OPEN
echo %mode1%
) ELSE (
echo coming into shorted
set %1=SHORTED
echo %mode1%
)
EXIT /B 0
echo mode is %mode1% doesn't print anything. Any help? I've hardcoded set mode=OPEN for testing purposes.
Each exit, exit /b or goto :eof implicitly does an endlocal, so you need a trick for your variable %1 to survive an endlocal. endlocal & set ... & goto :eof does the trick because the whole line gets parsed in one go:
#echo off
call :Mode mode1
echo mode is %mode1%
goto :eof
:Mode
setlocal enabledelayedexpansion
set "mode=OPEN"
IF "%mode%" == "OPEN" (
echo coming into open
endlocal&set "%1=OPEN"&goto :eof
) ELSE (
echo coming into shorted
endlocal&set "%1=SHORTED"&goto :eof
)
For the same reason, echo %mode1% in your subroutine does not print the variable.
Note: I changed set and if syntax to recommended quoted syntax.
I'm trying to simulate a while loop in Batch, here's my code:
#echo off
set test=0
:main
call:whileLSS %test% 4 :count
:whileLSS
if %1 LSS %2 (
echo %1
call%3
goto whileLSS
)
goto:EOF
:count
set /a test=%test%+1
goto:EOF
This just outputs 0s, instead of outputting "0 1 2 3" like I want it to.
The problem is that the loop goes forever because %1 doesn't have the most updated value of test.
Is this the right approach?
How do I update the value of %1?
Is there a way to not have to hardcode operators like LSS?
as you've been told, you can't change an Arg, you can take the arg as a reference and change the referenced var, this requires delayed expansion here.
Your first sub also wasn't separated from flow.
This Batch:
#echo off&Setlocal EnableDelayedExpansion
set test=0
:main
call:whileLSS test 4 :count
Goto :Eof
:whileLSS
if !%1! LSS %2 (
echo !%1!
call%3
goto whileLSS
)
goto:EOF
:count
set /a test+=1
goto:EOF
Produces this output:
0
1
2
3
Edit
The operator to the if may also be suppied as an arg:
#echo off&Setlocal EnableDelayedExpansion
set test=0
:main
call:while test LSS 4 :Increment
set test=10
call:while test GTR 4 :Decrement
Goto :Eof
:while
if !%1! %2 %3 (
echo !%1!
call %4 %1
goto while
)
goto:EOF
:Increment
set /a %1+=1
goto:EOF
:Decrement
set /a %1-=1
goto:EOF
Like this may be?
#echo off
:main
set /a a=1
set /P i=Enter i:
call:whileLSS %a% %i%
:whileLSS
echo %1
if %1 LSS %2 call:reinitialize %1 %2
goto:EOF
:reinitialize
set /a c=%1
set /a b=%c%+1
set /a d=%2
call:whileLSS %b% %d%
goto:EOF
Try this:
#echo off
Setlocal EnableDelayedExpansion
set test=0
:main
call :whileLSS !test! 4
Goto :Eof
:whileLSS
set i=%1
set j=%2
:loop
if !i! LSS !j! (
echo !i!
call :count
goto :loop
)
goto :EOF
:count
set /a i+=1
goto :EOF
REM test.bat
#ECHO OFF
IF NOT "%~1" == "" IF NOT "%~2" == "" (
SET /A "X=%~1+%~2"
echo %X%
)
Instead of getting the sum of the two numbers, it always prints the previous value of X:
>test.bat 1 2
ECHO is off
>test.bat 3 4
3
>test.bat 4 4
7
Is that because I'm not using EnableDelayedExpansion?
Edit: Why does it work when I move the echo out of the scope?
#ECHO OFF
IF NOT "%~1" == "" IF NOT "%~2" == "" (
SET /A "X=%~1+%~2"
GOTO why
)
GOTO :EOF
:why
echo %X%
As you pointed the delayed expansion - I suppose you know how to fix it - the only (afaik) reason to want to avoid it's usage is if you want the variables to survive endlocal statement and to use the variable value in brackets context meanwhile .So you can use additional CALL or tunneling:
#ECHO OFF
:: using call
IF NOT "%~1" == "" IF NOT "%~2" == "" (
SET /A "X=%~1+%~2"
call echo %%X%%
)
#ECHO OFF
:: using tunneling
setlocal enableDelayedExpansion
IF NOT "%~1" == "" IF NOT "%~2" == "" (
SET /A "X=%~1+%~2"
rem echo !X!
)
endlocal & set x=%x%
echo %x%
EDIT WAS MADE
The call starts a new sub-context of the command prompts with inherited variables.Additional %s are used to expand the variable in the next level.
Why does it work when I move the echo out of the scope?
#ECHO OFF
IF NOT "%~1" == "" IF NOT "%~2" == "" (
SET /A "X=%~1+%~2"
GOTO why
)
GOTO :EOF
:why
echo %X%
GOTO breaks the brackets context ,but in this case even without GOTO the correct value of the %x% will be printed because is outside of the brackets.
set File1 = C:\filepath
set File2 =C:\filepath
FOR %i IN (%FILE1%) DO SET DATE1=%%~ti\
FOR %i IN (%FILE2%) DO SET DATE2=%%~ti
IF "%DATE1%" GTR "%DATE2%" ECHO Files have same age && GOTO END
FOR %i IN ('DIR /B /O:D "%FILE1%" "%FILE2%"') DO SET NEWEST=%%i
ECHO Newer file is "%NEWEST%"
try this:
#echo off
rem --compares the age of two files
rem --by Vasil "npocmaka" Arnaudov
call :isOlder "C:\test.file1" "C:\test.file2"
goto :eof
:isOlder [%1 path to first file ; %2 path to second file]
setlocal
call :get_file_c_time "%~1" time1
call :get_file_c_time "%~2" time2
if "%time1%" LEQ "%time2%" (
echo YES
) else (
echo NO
)
goto :eof
:get_file_c_time [ %1 path to file; %2 variable to assign value ]
set file_path=%~1
if not exist "%file_path%" echo file %1 does not exist&& exit /b 1
if "%~2" equ "" echo need a secont parameter && exit /b 2
setlocal enableDelayedExpansion
for /f "skip=5 tokens=1,2,3,4,5,6 delims=/:.гчЈз " %%T in ('dir /tc "%file_path%"') do (
if "%%Y" EQU "PM" (
set /a "hour=%%W+12"
) else (
set hour=%%W
)
set ftime=%%V%%U%%T!hour!%%Y
goto :endfor
)
:endfor
endlocal & set "%~2=%ftime%"
goto :eof
It depends on TIME settings but in the most of the cases should work..
Another approach is with WMIC/WMI but I will need some time to create script
i have a batch file which should take inputs "-input1", "-input2" and "-input3". Here i need to validate the paramters like if user give the input parameter as "-test" or "-blah" or anyother parameter, then i should throw the error as "unregonized parameter". How can i achieve this? i tried by iterating through the paramters as %1 %2 etc. but i could not achieve the required behaviour.
IF "%1"=="" (
GOTO :ERROR3
)
IF "%1"=="-input1" (
SET value1=%2
)
#IF "%3"=="-input1" (
SET value1=%4
)
#IF "%5"=="-input1" (
SET value1=%6
)
#IF "%7"=="-input1" (
SET value1=%8
)
IF "%1"=="-input2" (
SET value1=%2
)
#IF "%3"=="-input2" (
SET value2=%4
)
#IF "%5"=="-input2" (
SET value2=%6
)
#IF "%7"=="-input2" (
SET value2=%8
)
IF "%1"=="-input3" (
SET value3=%2
)
#IF "%3"=="-input3" (
SET value3=%4
)
#IF "%5"=="-input3" (
SET value3=%6
)
#IF "%7"=="-input3" (
SET value3=%8
)
// some codes here
:ERROR1
ECHO "ERROR1"
GOTO :END
:ERROR2
ECHO "ERROR1"
GOTO :END
:ERROR3
ECHO Usage SAMPLE.bat -input1 "value1" -input2 "value2" -input3 "value3"
:END
Any help..
Here is a simple example of shifting through the parameters
#echo off
setlocal
set "value1="
set "value2="
set "value3="
:Parse
set "Param=%~1"
if not defined Param goto Validate
if "%Param%"=="-input1" set "value1=%2" & goto Next
if "%Param%"=="-input2" set "value2=%2" & goto Next
if "%Param%"=="-input3" set "value3=%2" & goto Next
goto Error1
:Next
shift & shift
goto Parse
:Validate
if defined value1 if defined value2 if defined value3 goto Main
goto Error2
:Main
echo %value1% %value2% %value3%
goto End
:Error1
echo Invalid Parameter: %1 %2
goto End
:Error2
echo Usage %~nx0 -input1 "value1" -input2 "value2" -input3 "value3"
goto End
:End
endlocal
The Batch file below allows you to modify the number and name of the parameters changing just one line.
#echo off
setlocal EnableDelayedExpansion
rem Define the list of parameters
set params=-input1 -input2 -input3
rem Initialize the array of parameters and their values
set n=0
for %%a in (%params%) do (
set /A n+=1
set param[%%a]=!n!
set "value!n!="
)
:nextParam
set "param=%~1"
shift
if not defined param goto start
if defined param[%param%] (
set "value!param[%param%]!=%~1"
shift
goto nextParam
)
echo ERROR - Bad parameter: %param%
goto :EOF
:start
echo Values of given parameters:
echo/
for /L %%i in (1,1,%n%) do echo Value%%i = "!value%%i!"