Jump to content

Batch script Shift command.


Recommended Posts

Win XP SP.3+

When a sub is Called and more than 9 command line parameters are passed to the sub is it possible to somehow Shift the command line parameters to allow the use of the 10th (and subsequent) parameters?

e.g. something like this:

Call :SubName %input1% %input2% %input3% %input4% %input5% output1 output2 output3 output4 output5

then as last line of the sub:

Endlocal&set %6=%hh%&set %7=%mm%&set %8=%ss%&set %9=%tot%&SHIFT&set %9=%final%&goto :eof

Obviously using Shift in that position doesn't work for me, is there another way to shift the parameters please?

Link to comment
Share on other sites


Win XP SP.3+

When a sub is Called and more than 9 command line parameters are passed to the sub is it possible to somehow Shift the command line parameters to allow the use of the 10th (and subsequent) parameters?

e.g. something like this:

Call :SubName %input1% %input2% %input3% %input4% %input5% output1 output2 output3 output4 output5

then as last line of the sub:

Endlocal&set %6=%hh%&set %7=%mm%&set %8=%ss%&set %9=%tot%&SHIFT&set %9=%final%&goto :eof

Obviously using Shift in that position doesn't work for me, is there another way to shift the parameters please?

What's wrong with using SHIFT in that position?

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS

CALL :SubName input1 input2 input3 input4 input5 output1 output2 output3 output4 output5
PAUSE
GOTO :EOF

:SubName
ECHO=[%6], [%7], [%8], [%9]
SHIFT
ECHO=[%9]

The last line echo's parameter 10 as parameter 9.

Link to comment
Share on other sites

Thank you Yzowl. Here's the script I'm working on and which works as far as my query goes although the results have not yet been proved.

@echo off
setlocal enabledelayedexpansion
cls

:: Get the start time
:: ------------------
call :GetTime StartHour StartMins StartSecs

pause
cls

:: Get the finish time
:: -------------------
call :GetTime StopHour StopMins StopSecs

:: Calculate elapsed time
:: ----------------------
call :Elapsed %StartHour% %StartMins% %StartSecs% %StopHour% %StopMins% ^
%StopSecs% Hours Minutes Seconds elsecs
echo Hours=!hours! Minutes=!minutes! Seconds=!seconds! Elapsed secs=!elsecs!


:: Add leading 0 to single digit values (for display purposes only)
:: ----------------------------------------------------------------
set cnt=1
:loop
set vars=StartHour StartMins StartSecs StopHour StopMins StopSecs
for /f "tokens=%cnt%" %%1 in ("%vars%") do (
if !%%1! lss 10 set %%1=0!%%1!
set /a cnt+=1
)
if %cnt% LSS 7 goto loop


:: Display outcomes
:: ----------------
echo.&echo.&echo.&echo.&echo.
echo Start time=%StartHour%:%StartMins%:%StartSecs%.
echo Stop time=%StopHour%:%StopMins%:%StopSecs%.
echo.
echo Elapsed seconds=%ElSecs%
echo.
echo Elapsed time=%Hours% hrs %Minutes% mins %Seconds% secs.
exit /b


:: Subs
:: ----
:GetTime
set vbs=%temp%\tmp.vbs

(
echo ThisTime=Time
echo WScript.Echo Hour(ThisTime^) ^&" "^& ^
Minute(ThisTime^) ^&" "^& ^
Second(ThisTime^)
)>%vbs%

for /f "tokens=1-3" %%a in ('cscript //nologo %vbs%') do (
set hh=%%a
set mm=%%b
set ss=%%c
)

del %vbs%
endlocal&set "%1=%hh%"&set "%2=%mm%"&set "%3=%ss%"&goto :EOF

:Elapsed
setlocal
set /a ElapsedSecs=3600*%4+60*%5+%6-(3600*%1+60*%2+%3)
if %ElapsedSecs% LSS 0 set /a ElapsedSecs=%ElapsedSecs%+(24*3600)
set /a h=(%ElapsedSecs%/3600)
set /a m=(%ElapsedSecs%/60)-60*%h%
set /a s=%ElapsedSecs%-60*(%ElapsedSecs%/60)
endlocal&set %7=%h%&set %8=%m%&set %9=%s%&set elsecs=%ElapsedSecs%&goto :EOF

Note the final line of the :Elapsed sub. If that line is changed to:

endlocal&set %7=%h%&set %8=%m%&set %9=%s%&Shift&set %9=%ElapsedSecs%&goto :EOF

or

endlocal&set %7=%h%&set %8=%m%&set %9=%s%
Shift
set %9=%ElapsedSecs%&goto :EOF

it appears not to return the %ElapsedSecs% content to Elsecs.

Link to comment
Share on other sites

If I may, it seems to me a bit overcomplex. :unsure:

Mind you, ONLY a hint:


@ECHO OFF
SETLOCAL
SET Before=%Time%
SET Before

FOR /F "tokens=1,2,3,4 delims=.," %%A IN ("%Before%") DO (
SET BEH=%%A
SET BEM=%%B
SET BES=%%C
)
SET /A BESeconds=%BEH%*60*60+%BEM%*60+%BES%
SET BESeconds

PAUSE
ECHO.

SET After=%Time%
SET After

FOR /F "tokens=1,2,3,4 delims=.," %%A IN ("%After%") DO (
SET AFH=%%A
SET AFM=%%B
SET AFS=%%C
)
SET /A AFSeconds=%AFH%*3600+%AFM%*60+%AFS%
SET AFSeconds
ECHO.

SET /A TES=%AFSeconds%-%BESeconds%
ECHO Total Elapsed Seconds %TES%
ECHO.


SET /A EH=%TES%/3600
SET /A REST=%TES%-%EH%*3600
SET /A EM=%REST%/60
SET /A REST=%REST%-%EM%*60
SET /A ES=%REST%
IF %EH:~1,1%.==. SET EH=0%EH%
IF %EM:~1,1%.==. SET EM=0%EM%
IF %ES:~1,1%.==. SET ES=0%ES%
ECHO Elapsed Time %EH%h %EM%m %ES%s

Check the actual separators used in your %Time%, in italian they are dot and comma, change accordingly.

jaclaz

Link to comment
Share on other sites

Try this revision of your script with a few, (compared to jaclaz's version), changes:

@echo off
setlocal enableextensions
cls

:: Get the start time
:: ------------------
call :GetTime StartHour StartMins StartSecs

REM Use ping with [num] to create approx [num-1] running command
ping -n 8 127.0.0.1 1>nul
cls

:: Get the finish time
:: -------------------
call :GetTime StopHour StopMins StopSecs

:: Calculate elapsed time
:: ----------------------
call :Elapsed %StartHour% %StartMins% %StartSecs% %StopHour% %StopMins% ^
%StopSecs% Hours Minutes Seconds elsecs
echo Hours=%hours% Minutes=%minutes% Seconds=%seconds% Elapsed secs=%elsecs%

:: Display outcomes
:: ----------------
echo.&echo.&echo.&echo.&echo.
echo Start time = %StartHour%:%StartMins%:%StartSecs%.
echo Stop time = %StopHour%:%StopMins%:%StopSecs%.
echo.
echo Elapsed seconds = %ElSecs%
echo.
echo Elapsed time = %Hours% hrs %Minutes% mins %Seconds% secs.
endlocal
goto :EOF

:: Subs
:: ----
:GetTime
set vbs=%temp%\tmp.vbs

(
echo ThisTime=Time
echo WScript.Echo Hour(ThisTime^) ^&" "^& ^
Minute(ThisTime^) ^&" "^& ^
Second(ThisTime^)
)>%vbs%

for /f "tokens=1-3" %%a in ('cscript //nologo %vbs%') do (
set %1=%%a
set %2=%%b
set %3=%%c
)

del %vbs%
goto :EOF

:Elapsed
set /a ElapsedSecs=3600*%4+60*%5+%6-(3600*%1+60*%2+%3)
if %ElapsedSecs% LSS 0 set /a ElapsedSecs=%ElapsedSecs%+(24*3600)
set /a hh=(%ElapsedSecs%/3600)
set /a mm=(%ElapsedSecs%/60)-60*%hh%
set /a ss=%ElapsedSecs%-60*(%ElapsedSecs%/60)
set "hh=10%hh%"&set "mm=10%mm%"&set "ss=10%ss%"
set %7=%hh:~-2%&set %8=%mm:~-2%&set %9=%ss:~-2%
SHIFT
set "%9=%ElapsedSecs%"
goto :EOF

Link to comment
Share on other sites

Mind you' date=' ONLY a hint: [/quote']

Thank you. Some of the script I posted is only to display information which will allow the wanted output, elapsed time, to be proved so will not be seen in the final version.

Yzöwl - Thank you again. Removing Setlocal and Endlocal and having Shift terminate with CRLF answered my query on Shift.

Link to comment
Share on other sites

Thank you. Some of the script I posted is only to display information which will allow the wanted output, elapsed time, to be proved so will not be seen in the final version.

Yep :), the idea was just that you don't actually *need* a .vbs (and a temp file :ph34r:) since you already have the %Time% variable, nor you *need* those calls with a big number of parameters, even if you are going to use subs/call, by initially converting the time in a "seconds-based-serial", you can have a single parameter that comprises all the needed info for each "timestamp".

jaclaz

Link to comment
Share on other sites

Check the actual separators used in your %Time%, in italian they are dot and comma, change accordingly.

You could always use your script to do that for you!

Example.cmd

@ECHO OFF & SETLOCAL
FOR /F "TOKENS=1-5 DELIMS=0123456789" %%A IN ("%TIME%") DO CALL :SUB %%A%%B%%C%%D%%E
GOTO :EOF
:SUB
FOR /F "TOKENS=1-4 DELIMS=%1" %%A IN ("%TIME%") DO (
ECHO=SET "HH=%%A" SET "MM=%%B" SET "SS=%%C" SET "TH=%%D")

Link to comment
Share on other sites

Like in ;):

@ECHO OFF
SETLOCAL
SET SEPS=%Time:~2,1%%Time:~8,1%
SET SEPS

If you can guarantee that each delimiter is positioned in those exact locations within the time variable, for all languages/formats then I can see its merits!

;)

Link to comment
Share on other sites

Like in ;):

@ECHO OFF
SETLOCAL
SET SEPS=%Time:~2,1%%Time:~8,1%
SET SEPS

If you can guarantee that each delimiter is positioned in those exact locations within the time variable, for all languages/formats then I can see its merits!

;)

NO, unfortunately it's NOT guaranteed :(.

The setting is in:

HKEY_CURRENT_USER\Control Panel\International\iTime

0=24 hour clock

1=12 hour clock

(which doesn't make a difference)

And in:

HKEY_CURRENT_USER\Control Panel\International\iTLZero

0=NO leading zero

1=Leading zero

(which DOES make a difference)

But then, if using REG.EXE, one could get the hh/mm/ss separator from

HKEY_CURRENT_USER\Control Panel\International\sTime

The GOOD news, is that if we go "backwards", that won't be a problem ;):

SET SEPS=%Time:~-3,1%%Time:~-6,1%

I don't think there is ANY settings in which the Time gets a different format from:

"(H)H/MM/SS/hs" whatever the / can be.

jaclaz

Edited by jaclaz
Link to comment
Share on other sites

The GOOD news, is that if we go "backwards", that won't be a problem ;):

SET SEPS=%Time:~-3,1%%Time:~-6,1%

I don't think there is ANY settings in which the Time gets a different format from:

"(H)H/MM/SS/hs" whatever the / can be.

Probably not but since I'm not aware of all of the formats I cannot be sure whether any add " [A|P]M" to the end!

Link to comment
Share on other sites

Jaclaz & Wyzöwl. Thank you for continuing with the thread, much is to be learned when members of your standing choose to discuss a topic on open forum.

My reason for opting for VBS is to make the script global rather than local, I'm not sure if the return from %time% is fixed globally or can be set locally in some other format. Anyways, the project will be a work-in-progress for some time, am now looking to use the VBS Timer function instead of the Time function.

V.

Link to comment
Share on other sites

I didn't think about the PM/AM :blushing: but I seem like not being able to have it in the %Time% :unsure:.

Is there a space between hh.mm.ss.hs and "AM" or "PM"?

Another attempt:

SET NOW=%Time%
SET SEPS4=%NOW%
FOR /L %%# IN (0,1,9) DO SET SEPS4=!SEPS4:%%#=!

Like in Sherlock Holmes' famous quote ;):

When you have eliminated the impossible, whatever remains, however improbable, must be the truth.

A "trailing" separator like A,P, or M won't make any harm.

Obviously if one sets the / in hh/mm/ss/hs as a number he truly deserves a failing batch! :)

And another one:


SET NOW=%Time%
SET SEPS5=%NOW%
FOR %%# IN ( A M P ) DO SET SEPS5=!SEPS5:%%#=!
SET SEPS5=%Now:~-6,1%%Now:~-3,1%

jaclaz

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...