Jump to content

Welcome to MSFN Forum
Register now to gain access to all of our features. Once registered and logged in, you will be able to create topics, post replies to existing threads, give reputation to your fellow members, get your own private messenger, post status updates, manage your profile and so much more. This message will be removed once you have signed in.
Login to Account Create an Account



Photo

Batch script Shift command.

- - - - -

  • Please log in to reply
13 replies to this topic

#1
Valerie

Valerie

    Junior

  • Member
  • Pip
  • 59 posts
  • Joined 09-March 06
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?


How to remove advertisement from MSFN

#2
Yzöwl

Yzöwl

    Wise Owl

  • Super Moderator
  • 4,574 posts
  • Joined 13-October 04
  • OS:Windows 7 x64
  • Country: Country Flag

Donator

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.

#3
Valerie

Valerie

    Junior

  • Member
  • Pip
  • 59 posts
  • Joined 09-March 06
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.

#4
jaclaz

jaclaz

    The Finder

  • Developer
  • 14,841 posts
  • Joined 23-July 04
  • OS:none specified
  • Country: Country Flag
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

#5
Yzöwl

Yzöwl

    Wise Owl

  • Super Moderator
  • 4,574 posts
  • Joined 13-October 04
  • OS:Windows 7 x64
  • Country: Country Flag

Donator

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


#6
Valerie

Valerie

    Junior

  • Member
  • Pip
  • 59 posts
  • Joined 09-March 06

Mind you, ONLY a hint:


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.

#7
jaclaz

jaclaz

    The Finder

  • Developer
  • 14,841 posts
  • Joined 23-July 04
  • OS:none specified
  • Country: Country Flag

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

#8
Yzöwl

Yzöwl

    Wise Owl

  • Super Moderator
  • 4,574 posts
  • Joined 13-October 04
  • OS:Windows 7 x64
  • Country: Country Flag

Donator

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")


#9
jaclaz

jaclaz

    The Finder

  • Developer
  • 14,841 posts
  • Joined 23-July 04
  • OS:none specified
  • Country: Country Flag

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

Sure :).

Like in ;):
@ECHO OFF
SETLOCAL
SET SEPS=%Time:~2,1%%Time:~8,1%
SET SEPS

jaclaz

#10
Yzöwl

Yzöwl

    Wise Owl

  • Super Moderator
  • 4,574 posts
  • Joined 13-October 04
  • OS:Windows 7 x64
  • Country: Country Flag

Donator

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!

;)



#11
jaclaz

jaclaz

    The Finder

  • Developer
  • 14,841 posts
  • Joined 23-July 04
  • OS:none specified
  • Country: Country Flag

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, 30 May 2010 - 08:33 AM.


#12
Yzöwl

Yzöwl

    Wise Owl

  • Super Moderator
  • 4,574 posts
  • Joined 13-October 04
  • OS:Windows 7 x64
  • Country: Country Flag

Donator

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!

#13
Valerie

Valerie

    Junior

  • Member
  • Pip
  • 59 posts
  • Joined 09-March 06
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.

#14
jaclaz

jaclaz

    The Finder

  • Developer
  • 14,841 posts
  • Joined 23-July 04
  • OS:none specified
  • Country: Country Flag
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




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users