?
Solved

Script Trouble

Posted on 2005-02-25
15
Medium Priority
?
1,257 Views
Last Modified: 2012-05-05
Not really sure how to title this... here's a little background.

I play this online baseball game and after each 2/3/4 game series I have to send data files, renamed and compressed, to the members of my league.  Typically, this has been done manually.  But there's no good reason I can think of that won't allow me to script it - only I'm lacking a certain degree of understanding in a key area and need some help (figuring SteveGTR, sirbounty, or DrWarezz are my best hopes, but anyone is welcome to comment).

In any case, note the script I have so far (lots of comments explaining what I need/am trying to do).

-------------------pack.cmd-------------------------------
@echo off
setlocal ENABLEDELAYEDEXPANSION

REM Check for the existance of %1
if "%1" == "" Goto ErrNoTeam

REM Set the visitor to env. var. to %1 (should be a 3 letter code)
REM For testing any 3 letter code will do, but BKA is the first I'm using myself.
set visitor=%1

REM Set my home team env. var. to my 3 letter code.
set home=SUN

REM Define the initial zip filename
set zipfile=%visitor%@%home%.ZIP

REM Change to directory with the data files
cd /d c:\cdrombb\export

REM Zip the data files into the zip file using InfoZip Command line.
zip -9 "%zipfile%" 2005WB*.*

REM Check for the existance of the packed directory - if not there, create it.
If Not Exist .\packed md .\packed

REM Move the previously zipped data files to the packed directory so they are
REM not referenced again.
move 2005wb*.* .\packed

REM Move the zipfile to the print directory containing the text files
move "%zipfile%" ..\print\2005wb

REM Change into the print directory.
cd ..\print\2005wb

REM Get a list of all boxscore print (box*.prt) files - each must be renamed
REM based on information found within the file.  I order from newest to oldest
REM because the oldest should be the first game and the zip file must be
REM renamed one more time to oldestgame %zipfile% - so in theory, the last
REM %gamedate% set should be the oldest date.
for /f "tokens=1 delims=" %%a in ('dir /o-d /b box*.prt') Do Call :ProcessGames %%a

REM Rename the zipfile to the final filename.
ren "%zipfile%" "%GameDate% %zipfile%"

REM Script now complete.
Goto End

:ProcessGames
REM This is my biggest problem area.  I can't seem to get this part to work
REM right.  I've had it seemingly skip the first file then correctly process the
REM the second two, setting gamedate correctly on those.
REM
REM This needs to be run for each game.  It should find the line starting with
REM "]BOXSCORE: " in the file %1 and then set the GameDate env. var. to the
REM last 9 characters of the line. Ideally, it will also remove any leading
REM and trailing spaces.  Lastly, the GameDate needs to be in a mmddyy format
For /f "tokens=1 skip=2 delims=" %%m in ('find "]BOXSCORE: " %1') Do (
      Set GameDate=%%m
      Set GameDate=%GameDate:~-9%
      Ren "%1"
)
GOTO :EOF

Goto End
:ErrNoTeam
Echo.
Echo Error!
Echo.
Echo Could not complete packing - you did not specify your opponant!
Echo.
:End
Set hometeam=
SET zipfile=
Set GameDate=
-------------------pack.cmd-------------------------------

Now, for your sample box*.prt files, the line of data retrieved looks like this for each file:

C:\CDROMBB\Print\2005WB>find "BOXSCORE" BOX*.PRT

---------- BOX0069.PRT
[1]BOXSCORE: 2005 Brookhurst Spartans At 2005 Sunnydale Vengence Demon 4/16/2005


---------- BOX0070.PRT
[1]BOXSCORE: 2005 Brookhurst Spartans At 2005 Sunnydale Vengence Demon 4/17/2005


---------- BOX0071.PRT
[1]BOXSCORE: 2005 Brookhurst Spartans At 2005 Sunnydale Vengence Demon 4/18/2005

Also, file info:
C:\CDROMBB\Print\2005WB>dir box*.prt
 Volume in drive C has no label.
 Volume Serial Number is A816-3E28

 Directory of C:\CDROMBB\Print\2005WB

02/25/2005  04:34 AM             6,695 BOX0069.prt
02/25/2005  05:12 AM             8,946 BOX0070.prt
02/25/2005  05:44 AM             7,335 BOX0071.prt

The end result should be:
Old file name --> new file name through script
BOX0069.PRT --> 041605 BKA@SUN.PRT
BOX0070.PRT --> 041705 BKA@SUN.PRT
BOX0071.PRT --> 041805 BKA@SUN.PRT

The final zip file name should be:
041605 BKA@SUN.ZIP

However you can get this working, I'll take it.  (It's gonna be run 50+ times by me in the next 6 months and MAYBE by 19 other guys too)  I figure most of it doesn't need to be edited, just that ProcessGames section.  Thanks all!
0
Comment
Question by:Lee W, MVP
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 5
  • 2
15 Comments
 
LVL 25

Expert Comment

by:InteractiveMind
ID: 13402601
Hey Leew,

you could try something like this perhaps:


FOR /F "delims=" %%L in (%~1) do CALL :PROCESS_LINE "%%L"
GOTO :EOF

:PROCESS_LINE
SET Line=%~1
IF /i "%Line:~2,9%" NEQ "]BOXSCORE" GOTO :EOF
SET GameDate=%Line:~-9%
SET GameDate=%GameDate: =%
REM  **  Process %GameDate% here



?

Regards,
>> IM
0
 
LVL 25

Expert Comment

by:InteractiveMind
ID: 13402617
You could probably shorten that also, like so:

FOR /F "delims=" %%L in (%~1) do (
   SET Line=%%L
   IF /i "%Line:~2,9%" NEQ "]BOXSCORE" GOTO :EOF
   SET GameDate=%Line:~-9%
   SET GameDate=%GameDate: =%
   
   REM ** Process %GameDate% here
)

0
 
LVL 25

Expert Comment

by:InteractiveMind
ID: 13402657
Hmm.. Okay, the first snippet seems to work - but the second doesn't.

>> IM
0
Veeam Task Manager for Hyper-V

Task Manager for Hyper-V provides critical information that allows you to monitor Hyper-V performance by displaying real-time views of CPU and memory at the individual VM-level, so you can quickly identify which VMs are using host resources.

 
LVL 25

Expert Comment

by:InteractiveMind
ID: 13402706
Then add these lines to turn the format of mm/dd/yyyy into mmddyy:

...
SET GameDate=%GameDate:/=%
SET mm=%GameDate:~0,2%
SET dd=%GameDate:~2,2%
SET yy=%GameDate:~-2%
SET GameDate=%mm%%dd%%yy%
...
0
 
LVL 25

Expert Comment

by:InteractiveMind
ID: 13402726

:ProcessGames
FOR /F "delims=" %%L in (%~1) do CALL :PROCESS_LINE "%%L"
GOTO :EOF

:PROCESS_LINE
SET Line=%~1
IF /i "%Line:~2,9%" NEQ "]BOXSCORE" GOTO :EOF
SET GameDate=%Line:~-9%
SET GameDate=%GameDate: =%
SET GameDate=%GameDate:/=%
SET mm=%GameDate:~0,2%
SET dd=%GameDate:~2,2%
SET yy=%GameDate:~-2%
SET GameDate=%mm%%dd%%yy%

REM ** Process %GameDate% here . . .

GOTO :EOF

0
 
LVL 30

Accepted Solution

by:
SteveGTR earned 2000 total points
ID: 13403643
I always have problems with the delayed expansion processing. Just when I think I have it down, I get it wrong. Luckly testing it out restores my knowledge --- at least for that day. Today is a good day and I got it right the first time:

For /f "tokens=1 skip=2 delims=" %%m in ('find "]BOXSCORE: " %1') Do (
     Set GameDate=%%m
     Set GameDate=!GameDate:~-9!
     Ren "%1"
)

This is the key line: Set GameDate=!GameDate:~-9!

Good Luck,
Steve
     
0
 
LVL 25

Expert Comment

by:InteractiveMind
ID: 13403678
Damn you, Steve. :-P  lol

What is the difference between using the '!' and '%' to indicate variables? On the rare occasion of me using them, I've treated them as if they're the same - in order to make variables, side-by-side, clearer.

?

Cheers,
>> IM
0
 
LVL 30

Expert Comment

by:SteveGTR
ID: 13403875
By default DOS preprocesses environment variables in blocks. In this case the block is the part of the for statement that is delimetered by the parens ( ):

For /f "tokens=1 skip=2 delims=" %%m in ('find "]BOXSCORE: " %1') Do (
     Set GameDate=%%m
     Set GameDate=!GameDate:~-9!
     Ren "%1"
)

A simple example shows this:

@echo off

set dirline=

for %%a in (*.*) do (
  set dirline=%%a
  echo dirline=%dirline%
)

This batch prints "dirline=" for each entry in directory. That's because DOS preprocesses the dirline environment variable upon entry to the block. In this case it's set to nothing.

In order to get it to work you have to enable delayed expansion and use '!' when you want to reference the current value of the environment variable:

@echo off

setlocal ENABLEDELAYEDEXPANSION

set dirline=

for %%a in (*.*) do (
  set dirline=%%a
  echo dirline=!dirline!
)

Here's what DOS says (set /?):

Delayed environment variable expansion allows you to use a different
character (the exclamation mark) to expand environment variables at
execution time.  If delayed variable expansion is enabled, the above
examples could be written as follows to work as intended:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "!VAR!" == "after" @echo If you see this, it worked
    )

    set LIST=
    for %i in (*) do set LIST=!LIST! %i
    echo %LIST%
0
 
LVL 25

Expert Comment

by:InteractiveMind
ID: 13403969
Ah, I get it.
You the man, Steve.   :-)

Cheers,
>> IM
0
 
LVL 96

Author Comment

by:Lee W, MVP
ID: 13406635
Thanks guys - here's the final script.  I did mention in the comments for "ProcessGames":

REM This needs to be run for each game.  It should find the line starting with
REM "]BOXSCORE: " in the file %1 and then set the GameDate env. var. to the
REM last 9 characters of the line. Ideally, it will also remove any leading
REM and trailing spaces.  Lastly, the GameDate needs to be in a mmddyy format

Steve got the first part, but I didn't see anything addressing the second part, renoted above.
I've worked around it - as you'll see below - and think everything works fine - or so it seems.  If you can suggest a more efficient way of dealing the the variable date string, I'd appreciate it.  I'm going to leave the question open a little longer so I can play a couple more series to test it on them.  But for the moment, it looks like Steve won (thanks to you both though).




@echo off
setlocal ENABLEDELAYEDEXPANSION

REM Set the visitor to env. var. to %1 (should be a 3 letter code)
set visitor=%1
If "%visitor%" == "" SET /p Visitor=Who was the visiting team (3 letter code):

REM Set my home team env. var. to my 3 letter code.
set home=SUN

REM Define the initial zip filename
set zipfile=%visitor%@%home%.ZIP

REM Change to directory with the data files
cd /d c:\cdrombb\export

REM Zip the data files into the zip file using InfoZip Command line.
zip -9 "%zipfile%" 2005WB*.*

REM Check for the existance of the packed directory - if not there, create it.
If Not Exist .\packed md .\packed

REM Move the previously zipped data files to the packed directory so they are
REM not referenced again.
move 2005wb*.* .\packed

REM Move the zipfile to the print directory containing the text files
move "%zipfile%" ..\print\2005wb

REM Change into the print directory.
cd ..\print\2005wb

REM Get a list of all boxscore print (box*.prt) files - each must be renamed
REM based on information found within the file.  I order from newest to oldest
REM because the oldest should be the first game and the zip file must be
REM renamed one more time to oldestgame %zipfile% - so in theory, the last
REM %gamedate% set should be the oldest date.
for /f "tokens=1 delims=" %%a in ('dir /o-d /b box*.prt') Do Call :ProcessGames %%a

REM Packup the boxscores
If not exist .\packed md packed
zip -9 %zipfile% 0*.prt
move 0*.prt packed

REM Rename the zipfile to the final filename.
ren "%zipfile%" "%mm%%dd%%yy% %zipfile%"

REM Script now complete.
Goto End

:ProcessGames
REM This needs to be run for each game.  It should find the line starting with
REM "]BOXSCORE: " in the file %1 and then set the GameDate env. var. to the
REM last 9 characters of the line. Ideally, it will also remove any leading
REM and trailing spaces.  Lastly, the GameDate needs to be in a mmddyy format

For /f "tokens=1 skip=2 delims=" %%m in ('find "]BOXSCORE: " %1') Do (
      Set GameDate=%%m
      Set GameDate=!GameDate:~-9!
      set yy=!gamedate:~7,2!
      set mm=!gamedate:~0,2!
      set dd=!gamedate:~2,2!
      if "!mm!" == " 4" Set mm=04
      if "!mm!" == " 5" Set mm=05
      if "!mm!" == " 6" Set mm=06
      if "!mm!" == " 7" Set mm=07
      if "!mm!" == " 8" Set mm=08
      if "!mm!" == " 9" Set mm=09
      if "!mm!" == "4/" Set mm=04
      if "!mm!" == "5/" Set mm=05
      if "!mm!" == "6/" Set mm=06
      if "!mm!" == "7/" Set mm=07
      if "!mm!" == "8/" Set mm=08
      if "!mm!" == "9/" Set mm=09
      if "!dd!" == "1/" set dd=01
      if "!dd!" == "2/" set dd=02
      if "!dd!" == "3/" set dd=03
      if "!dd!" == "4/" set dd=04
      if "!dd!" == "5/" set dd=05
      if "!dd!" == "6/" set dd=06
      if "!dd!" == "7/" set dd=07
      if "!dd!" == "8/" set dd=08
      if "!dd!" == "9/" set dd=09
      Ren "%1" "!mm!!dd!!yy! !visitor!@!home!.prt"
)

GOTO :EOF

:End
REM Cleanup environment variables
Set home=
SET zipfile=
Set GameDate=
set mm=
set dd=
set yy=
set visitor=
0
 
LVL 30

Expert Comment

by:SteveGTR
ID: 13407632
Sorry leew, I didn't see that part. I tend to not follow directions well ;)

I believe your code will fail when you process a date with a two digit year and month. Here's some code that does away with the need for the delayed expansion and also can process more date variations. Give it a try:

...

:PROCESS

for /f "skip=2 delims=" %%a in ('find "]BOXSCORE: " %1') do call :PROCESS_LINE %%a

goto :EOF

:PROCESS_LINE

set lastToken=

:NEXT_TOKEN

if "%1"=="" goto LAST_TOKEN

set lastToken=%1

shift

goto NEXT_TOKEN

:LAST_TOKEN

for /f "tokens=1-3 delims=/" %%a in ('echo %lastToken%') do (
  call :ADJUST_PART mm %%a
  call :ADJUST_PART dd %%b
  call :ADJUST_PART yy %%c Y
)

ren "%1" "%mm%%dd%%yy% %visitor%@%home%.prt"

goto :EOF

:ADJUST_PART

set %1=%2

if "%3"=="Y" goto ADJUST_YEAR

set _t=1%2

if /I %_t% LSS 100 set %1=0%2

goto :EOF

:ADJUST_YEAR

set _t=1%2

if /I %_t% LSS 1000 set %1=20%2
0
 
LVL 25

Expert Comment

by:InteractiveMind
ID: 13409617
Steve,
for your last attempt, above - wouldn't you need to change:

for /f "skip=2 delims=" %%a in ('find "]BOXSCORE: " %1') do call :PROCESS_LINE %%a

to:

for /f "skip=2 delims=" %%a in ('find "]BOXSCORE: " %1') do call :PROCESS_LINE "%%a"

(note the quotes round the argument).

Seeing as the string that you're extracting is likely to have spaces in it....?? (And then of course, you'd need to alter the rest of the code a little bit: %1 to %~1)..

Surely?

(Don't worry, I'm not desperately trying to claim some points here... full points to Steve, is fine by me - but just thought that Lee may have some trouble if that alteration isn't made..?)

>> IM
0
 
LVL 30

Expert Comment

by:SteveGTR
ID: 13410123
No, the point of PROCESS_LINE is to pick off the last word of the line. I'm using the fact that parameters are seperated by whitespace to parse them in PROCESS_LINE.
0
 
LVL 30

Expert Comment

by:SteveGTR
ID: 13433687
leew -- you had any success with this code?
0
 
LVL 96

Author Comment

by:Lee W, MVP
ID: 13433955
Sorry Steve, I got so far ahead into the project that it's gone from something specific into something generic that uses a .ini file to configure it.  So now I'm a little wary of altering it significantly.  Appreciate the efforts though.
0

Featured Post

Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Using dates in 'DOS' batch files has always been tricky as it has no built in ways of extracting date information.  There are many tricks using string manipulation to pull out parts of the %date% variable or output of the date /t command but these r…
One of my most closely kept secrets is revealed in this discussion How to output text on the same line This question was recently posted in EE by Simon336697 (http://www.experts-exchange.com/Programming/Languages/Scripting/Shell/Batch/Q_2459…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question