Page 1 of 1

How do I determine the number of arguments?

Posted: 24 Aug 2009 16:14
by ldrechsler
Hi,

I want to allow users to pass up to 5 arguments into my batch file. For example, a user might enter MYBATCH Arg1 Arg2 Arg3. Only the first argument is required.

I also want to set a variable to hold the args. Using the above example, I would try

Code: Select all

myvar="Arg1 Arg2 Arg3"


Any ideas?

This is what I've come up with so far...but it's embarrassingly insufficient (is embarrassingly a word?).

Code: Select all

@echo off
cls

set VarName=This is my variable
echo %VarName%

for /F "tokens=1-5 " %%A in ("%VarName%") do set "var1=%%A" & set "var2=%%B" & set "var3=%%C" & set "var4=%%D" & set "var5=%%E"

Posted: 24 Aug 2009 21:16
by DosItHelp
ldrechsler,

Try:

Code: Select all

set var1=%~1
set var2=%~2
set var3=%~3
set var4=%~4
set var5=%~5

echo.var1 is %var1%
echo.var2 is %var2%
echo.var3 is %var3%
echo.var4 is %var4%
echo.var5 is %var5%


DOS IT HELP? :wink:

Posted: 25 Aug 2009 09:09
by avery_larry
If you want 1 variable to hold all the arguments passed, then:


set myvar=%*

If you want multiple variables -- each assigned to one of the arguments, then do what DIH shows.

Posted: 27 Aug 2009 08:39
by jaffamuffin
http://www.dostips.com/forum/viewtopic. ... highlight=

This should be helpful and fairly clear to understand. It's pretty flexible and fairly robust i think.

posted here as well :


Code: Select all

@echo off
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION

SET InDir=X:\tobeprocessed
SET OutDir=X:\processed
SET tifDir=%OutDir%\tifs
SET jpgDir=%OutDir%\jpgs
SET bakDir=X:\BACKUP
SET JPGSZ=75
SET JPGQL=40
SET LOGDIR=X:\logs
SET BKTYP=1 2+3 4 5+6
SET AddZ=1
SET DEBUG=
SET VERB=1

ECHO Checking Commandline Parameters...
SET PARAMCOUNT=0
GOTO _processcmdline
GOTO:EOF


:_start
ECHO.
ECHO Using these values:
echo.INDIR      = %InDir%
echo.OUTDIR     = %OutDir%
echo.TIFDIR     = %tifDir%
echo.JPGDIR     = %jpgDir%
echo.BAKDIR     = %bakDir%
echo.LOGDIR     = %LOGDIR%
echo.IMGPROGRAM = %IMGCMD%
echo.JPGRESIZE  = %JPGSZ%
echo.JPGQUALITY = %JPGQL%
echo.BKTYP      = %BKTYP%
echo.ADDZ       = %AddZ%
echo.VERBOSITY  = %VERB%
ECHO Pause for 5 seconds...
ping -n 6 127.0.0.1 >NUL
ECHO Let's do it...
GOTO:EOF



:_processcmdline
IF "%1"=="/?" GOTO _syntax
IF "%1"=="-help" GOTO _help
SET FOUND=0
SET /A PARAMCOUNT=PARAMCOUNT+1
SET PARAMS=-q -v -vv -vvvv -imgcmd -jpg -resize -indir -outdir -bakdir -backdir -bakup -backup -logdir -addz -debug
FOR %%A IN (%PARAMS%) DO (
   IF "%1"=="%%A" SET FOUND=1
)
IF !FOUND!==0 (
   ECHO Unknown option: %1 at Parameter: !PARAMCOUNT!
   ECHO Possible spaces in directory paths or spelling error?
   GOTO:EOF
)
IF !FOUND!==1 ECHO Parameter OK: %1
IF "%1"=="-debug" SET DEBUG=PAUSE
IF "%1"=="-q" SET VERB=0
IF "%1"=="-v" SET VERB=2
IF "%1"=="-vv" SET VERB=3
IF "%1"=="-vvv" SET VERB=4
IF "%1"=="-imgcmd" SET IMGCMD=%2 & SHIFT
IF "%1"=="-jpg" SET JPGQL=%2 & SHIFT
IF "%1"=="-resize" SET JPGSZ=%2 & SHIFT
IF "%1"=="-indir" SET InDir=%2 & SHIFT
IF "%1"=="-outdir" SET OutDir=%2 & SHIFT
IF "%1"=="-bakdir" SET BakDir=%2 & SHIFT
IF "%1"=="-backdir" SET BakDir=%2 & SHIFT
IF "%1"=="-bakup" SET BakDir=%2 & SHIFT
IF "%1"=="-backup" SET BakDir=%2 & SHIFT
IF "%1"=="-logdir" SET LOGDIR=%2 & SHIFT
IF "%1"=="-addz" SET AddZ=%2 & SHIFT
SHIFT                               
IF "%1" == "" GOTO:_start       
GOTO _processcmdline

Great Stuff!!!

Posted: 27 Aug 2009 15:37
by ldrechsler
This is great stuff...thanks guys. I still haven't been able to get the results I want though. When I first started on this project, I was simply passing single element variables to MyScript.bat (i.e. MyScript.bat Var1 Var2 Var3...). A new requirement to handle multi-element variables threw that out the window though.

To put this command in a real world context, I have a SQL job that's sending the following command line to a script that schedules the command specified in -Script as a task on a remote server.

xp_CMDSHELL Path\MainScript -Server Server1 -Name Task_Name -Script MyScript.bat /Arg1 xyz /Arg2 abc /Arg3 tuv def lmn /Arg4 Last Arg

The arguments prefaced with the "-" are used by MainScript while the arguments prefaced with the "/" are used by MyScript. Some arguments in MyScript.bat contain spaces and have an undefined number of elements, seen in /Arg3 and /Arg4 above. That's the task that gets scheduled.

So, within MyScript.bat, I need to set the internal variables with the arguments passed to it. Since I don't know how many elements are in an argument, I can't simply assign variable names to each argument. If the arguments were only a single word, using the commandline above, I would just:

Code: Select all

set Var1=%1
set Var2=%2
set Var3=%3
set Var4=%4
etc.

...but this doesn't work with /Arg3 and /Arg4. And, I can't seem to get this working with jaffamuffin's script either (that's a great script BTW). Any more ideas?

Posted: 27 Aug 2009 16:28
by jaffamuffin
OK I think what you need to do is parse the params for your /arg thing, and then 'sub-parse' each /arg thing found.

So rough (bad) pseduo code:

Code: Select all

:main
read current param and cut off last letter and store it as %number%
  :loop1
    if %1 (less the last letter) = arg
      OK, parse values and read first 3 letters
          if any of these next values are 'arg' then all params have been read for that arg (in the immediate case you'd have 2 arg in a row =bad
       return goto main
           else
           store value as arg%number%_%count%=%1
          increment count
          shift
          goto loop1



bleh it's late hope that helps. I'll maybe look at it later.... :)

edit the above would give something like this for your example above:

/Arg1 xyz /Arg2 abc /Arg3 tuv def lmn /Arg4 Last Arg

arg1_1=xyz
arg2_1=abc
arg3_1=tuv
arg3_2=def
arg3_3=lmn
arg4_1=Last
arg4_2=Arg <-- -o_O - using arg as a switch and a value may be a problem. It would be possible to code around it if you cut the arg number and found it to be EMPTY?!

oh and i never accounted for the slashes, eit

RESOLUTION

Posted: 28 Aug 2009 14:59
by ldrechsler
Wow, it was actually easier than I thought. Thanks jaffamuffin for pointing me in the right direction! Here's a sample command line:

MyScript.bat /ARG1 One-var /ARG2 Two vars /ARG3 3 vars here /ARG4 One more var here /ARG5 1 2 3 4 5 /ARG6 4 + 1 + 1 = /ARG7 You guessed it, 4+1+1 = 7 !

Code: Select all

-- Capture the command-line arguments into a single variable
   /ARG1 One-var /Arg2 Two vars /Arg3 3 vars here /ARG4 One more var here /ARG5 1 2 3 4 5 /ARG6 4 + 1 + 1 = /ARG7 You guessed it, 4+1+1 = 7 !

-- Split the arguments into individual variables
ARG1: ARG1 One-var
ARG2: Arg2 Two vars
ARG3: Arg3 3 vars here
ARG4: ARG4 One more var here
ARG5: ARG5 1 2 3 4 5
ARG6: ARG6 4 + 1 + 1 =
ARG7: ARG7 You guessed it, 4+1+1 = 7 !

-- Trim off the /ARG switch

-- And there you have it!
ARG1:  One-var
ARG2:  Two vars
ARG3:  3 vars here
ARG4:  One more var here
ARG5:  1 2 3 4 5
ARG6:  4 + 1 + 1 =
ARG7:  You guessed it, 4+1+1 = 7 !


...and here is the code for MyScript.bat:

Code: Select all

@echo off
cls

set myvar=%*

echo.-- Capture the command-line arguments into a single variable
for /f %%a in ("%myvar%") do set arg=%%a
echo.   %myvar%
echo.

echo.-- Split the arguments into individual variables
for /f "tokens=1-7 delims=/" %%a in ("%myvar%") do set ARG1=%%a&set ARG2=%%b&set ARG3=%%c&set ARG4=%%d&set ARG5=%%e&set ARG6=%%f&set ARG7=%%g
echo ARG1: %ARG1%
echo ARG2: %ARG2%
echo ARG3: %ARG3%
echo ARG4: %ARG4%
echo ARG5: %ARG5%
echo ARG6: %ARG6%
echo ARG7: %ARG7%
echo.

echo.-- Trim off the /ARG switch
set ARG1=%ARG1:~4%
set ARG2=%ARG2:~4%
set ARG3=%ARG3:~4%
set ARG4=%ARG4:~4%
set ARG5=%ARG5:~4%
set ARG6=%ARG6:~4%
set ARG7=%ARG7:~4%
echo.

echo.-- And there you have it!
echo.ARG1: %ARG1%
echo.ARG2: %ARG2%
echo.ARG3: %ARG3%
echo.ARG4: %ARG4%
echo.ARG5: %ARG5%
echo.ARG6: %ARG6%
echo.ARG7: %ARG7%


So, there you have it...a convenient way to parse multi-variable arguments passed into a batch script. As you can see, I've used code from everyone here and I just want to thank you all for your help!

Posted: 29 Aug 2009 12:28
by jaffamuffin
nice. As i wrote the last line in my previous reply I thought about splitting on the / .. glad to see you got a solution