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!"
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.
My batch file accepts 4 arguments:
mybatch.bat -name=path leading to a file -type=some predefined enum
i then pass it to another batch file to check if both values are given.
My question is when i receive path containing a space how do i extract the location of the file. It might or might not contain space.
I know how to handle without space.
Contents of main bat file
set arg1=%~1
set arg2=%~2
set arg3=%~3
set arg4=%~4
set name=
set sType=
if "%*" == "" (
goto Help
)
call parse.bat
if %errorlevel% equ 1 (
goto error
) else if %errorlevel% equ 2 (
goto Help
)
set file=%name%
FOR %%i IN ("%file%") DO (
set filedrive=%%~di
set filepath=%%~pi
set filename=%%~ni
)
set fileLoc=%filedrive%%filepath%
set name=%filename%
Contents of parse.bat
if defined arg5 echo "invalid argument" & goto :error
if /I %arg1% equ -help (
exit /b 2
) else if /I %arg1% equ -h (
exit /b 2
)
if /I %arg1% equ -name (
set name=!arg2!
) else if /I %arg1% equ -sType (
set sType=%arg2%
) else (
goto :error
)
if not defined arg3 goto :chkparam
if /I %arg3% equ -name (
set name=%arg4%
) else if /I %arg3% equ -sType (
set sType=%arg4%
) else (
goto :error
)
The moment i enter a path which has space in between it says :
main.bat -name="c:\tmp\New folder\file2.txt" -stype=other
folder\file2.txt" -stype=other" was unexpected at this time.
How to split string with the delim=string
E.g:
split string
"sssssMssssMYSTR___M___MYSTRzzzzzzMzzzz"
by
delim="MYSTR"
and result should be:
sssssMssss
___M___
zzzzzzMzzzz
Such code
for /f "tokens=1,2 delims=MYSTR" %%A in ("sssssMssssMYSTR___M___MYSTRzzzzzzMzzzz") do (
set fn1=%%A
)
doesn't work/ It splits only using first letter by 'M'
How to split by word?
#echo off
setlocal EnableDelayedExpansion
set "string=sssssMssssMYSTR___M___MYSTRzzzzzzMzzzz"
rem Do the split:
set i=1
set "fn!i!=%string:MYSTR=" & set /A i+=1 & set "fn!i!=%"
set fn
Output:
fn1=sssssMssss
fn2=___M___
fn3=zzzzzzMzzzz
You may review this topic for a detailed explanation on the method used...
try with split.bat (you can use both as a function or a separate bat file (does not handle well !,% and ")) :
#echo off
setlocal
call :split "sssssMssssMYSTR___M___MYSTRzzzzzzMzzzz" MYSTR 1 spl1
echo %spl1%
call :split "sssssMssssMYSTR___M___MYSTRzzzzzzMzzzz" MYSTR 2 spl2
echo %spl2%
call :split "sssssMssssMYSTR___M___MYSTRzzzzzzMzzzz" MYSTR 3
rem echo %spl2%
endlocal & exit /b %errorlevel%
:split [%1 - string to be splitted;%2 - split by;%3 - possition to get; %4 - if defined will store the result in variable with same name]
::http://ss64.org/viewtopic.php?id=1687
setlocal EnableDelayedExpansion
set "string=%~2%~1"
set "splitter=%~2"
set /a position=%~3
set LF=^
rem ** Two empty lines are required
echo off
for %%L in ("!LF!") DO (
for /f "delims=" %%R in ("!splitter!") do (
set "var=!string:%%~R%%~R=%%~L!"
set "var=!var:%%~R=%%~L!"
if "!var!" EQU "!string!" (
echo "%~1" does not contain "!splitter!" >&2
exit /B 1
)
)
)
if "!var!" equ "" (
endlocal & if "%~4" NEQ "" ( set "%~4=")
)
if !position! LEQ 0 ( set "_skip=" ) else (set "_skip=skip=%position%")
for /f "eol= %_skip% delims=" %%P in ("!var!") DO (
if "%%~P" neq "" (
set "part=%%~P"
goto :end_for
)
)
set "part="
:end_for
if not defined part (
endlocal
echo Index Out Of Bound >&2
exit /B 2
)
endlocal & if "%~4" NEQ "" (set %~4=%part%) else echo %part%
exit /b 0
We are trying to make a switch statement which is parsing command line argument in a batch file.
mybatch.bat -a 10 -b name -c India --zipcode 20
Only -a, -b, -c are parsing parameter (which is starts with -).
Our code will be like:
for %%x in (%*) do (
switch(%%x) (
case a:
SET first_number=%arg%
break
case b:
SET name=%arg%
case c:
for %%x in (%*) do (
SET place =%place% %arg%
)
default:
echo wrong parameter
)
The Batch file below parses all arguments that start with - and creates a series of variables that start with "option" and the names and values of all options given:
#echo off
setlocal EnableDelayedExpansion
set "option="
for %%a in (%*) do (
if not defined option (
set arg=%%a
if "!arg:~0,1!" equ "-" set "option=!arg!"
) else (
set "option!option!=%%a"
set "option="
)
)
SET option
For example:
>test -a 10 -b name -c India --zipcode 20
option--zipcode=20
option-a=10
option-b=name
option-c=India
This way, you need to make no changes in the parsing code if you want to add/change/delete any option, just use the value of the option you want. For example:
if defined option-x (
echo Option -x given: "%option-x%"
) else (
echo Option -x not given
)
Normally you try to keep things simple and have a set order for the parameters. To handle parameters in any, random order is a lot more effort than just knowing that %1 = number, %2 = name and %3 onwards = place.
That said, here's an attempt at a solution. I'm ignoring --params in the place section, just joining the values together.
#echo off
setlocal
:loop
if x%1 equ x goto done
set param=%1
if %param:~0,1% equ - goto checkParam
:paramError
echo Parameter error: %1
:next
shift /1
goto loop
:checkParam
if "%1" equ "-a" goto A
if "%1" equ "-b" goto B
if "%1" equ "-c" goto C
goto paramError
:A
shift /1
set first_number=%1
goto next
:B
shift /1
set name=%1
goto next
:C
set place=
:GetPlaces
shift /1
set param=%1
if not defined param goto donePlaces
if %param:~0,2% equ -- (
shift /1
goto processPlace
)
if %param:~0,1% equ - goto donePlaces
:processPlace
echo.%place%
if x%1 neq x (
set place=%place% %1
goto GetPlaces
)
:donePlaces
rem remove leading space
if defined place set place=%place:~1%
goto loop
:done
echo num=%first_number% name=%name% place=%place%
there's no switch command in batch.You need to workaround this with if statements:
#echo off
setlocal enableDelayedExpansion
for /l %%a in (1,2,6) do (
set /a next=%%a+1
set param=%%a
call set _param=%%!param!
call set _next=%%!next!
rem echo -!next! -!_next! #!_param! #%%a
if "!_param!" equ "-a" (
set first_number=!_next!
)
if "!_param!" equ "-b" (
call set name=!_next!
)
if "!_param!" equ "-c" (
set place=!_next!
)
)
for %%a in (place first_number name) do (
if not defined %%a set wrong_parameter=1
)
if defined wrong_parameter (
echo wrong parameter
)
echo %place% %first_number% %name%
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