?
Solved

DOS Shell Script - Searching Strings

Posted on 2012-08-17
19
Medium Priority
?
1,632 Views
Last Modified: 2012-08-20
Hi,

I am writing a DOS batch program that, among other things needs to rename a file with a date stamp based on a format passed in part of an argument. i need to parse this format identifier from the argument (variable) to determine how to format the date stamp.

The variable  will come is as: "FileNameFormatOtherStuff.extension" an example would be: "filenameccyymmdd.pgp" where ccyymmdd would mean to create a variable to later be used to rename a file to something like: "FileName20120816.pgp" i can receive various formats the key being the occurrence of a specific group of characters like: ccyymmdd or yymm or yymmdd etc... there are about ten combinations possible. In some cases the string could have the identifier in the middle like this: "FileNameccyymmdddMoreStuff.csv".

I have no problem with parsing a date and building the correct filename, what i do need to determine is the following items: the length of the entire string, the starting position of the format identifier within the string the ending position of the format identifier and the position of the "." which is not always at the end of the format identifier.

I have been trying to use the FOR/f command and am failing miserably.....HELP!

Thanks! -  Jennifer
0
Comment
Question by:jennifer_EDI_Gal
  • 8
  • 7
  • 3
18 Comments
 
LVL 43

Expert Comment

by:Steve Knight
ID: 38305968
Hmm, would probably be much easier doing this in a few lines of VBS than batch though all is possible one way or another.

Using for loop you can split the filename at the . using %%~xA and %%~nA to get name and extension but to find the date bit in the middle.  How do you determine between

MyBikeIs1500cc-YY-MM-DD.doc

being CC or century... etc.

i.e. is there a rule for how to find the dd/mm/yy bits etc - is this human entered or from a different system?

if it is always certain formats then you could first test for ccyymmdd then yymmdd etc.

You can do a search and replace, e.g.

set myfilename=%myfilename:ccyymmdd=20120502%
set myfilename=%myfilename:yymmdd=120502%
set myfilename=%myfilename:yymm=1205%
set myfilename=%myfilename:mmdd=0502%

etc.

Would suggest getting the date using VBS (or WMIC) methods which is why I wondered if the whole lot in VBS might be better plan?
I use this for dates: http://www.experts-exchange.com/Programming/Languages/Visual_Basic/VB_Script/Q_27823783.html 

Steve



Steve
0
 

Author Comment

by:jennifer_EDI_Gal
ID: 38306106
Steve,

Thanks for the input. there is a list of about 700 file names that need to be routed to several different applications, including database parsing of the content, archiving, cryptographic operations etc.... i do not have the luxury of a real development environment only SQL server, which could more readily parse a variable from a stored procedure but i am not sure about passing the results back to the calling DOS shell, it may be more bother then going this route.

I am literally getting the characters "ccyymmdd" etc... in the file name. getting the date is not an issue, i already have parsed it into variables i call %mm%, %dd% etc... i just need to know which format to arrange them into based on the content of this string, which btw is generated by some legacy application we have no control over.

the search and replace may be a viable answer. I can certainly replace someting like "yy" with %yy%.

this operation is the final step before they get FTP'd to 700 different trading partners out there in the ozone. it is these partners who define what the date stamp needs to look like so they can automagically parse them on their side of the equation.

could you please show me an example of how to substitute a variable like that? Say replace the literal "yy" with the content of my %yy% variable within a string, lets call it %output_file%?

Thanks again,
Jen
0
 
LVL 43

Accepted Solution

by:
Steve Knight earned 2000 total points
ID: 38306248
Try this.... you can see a potential issue though perhaps and why I suggesting replacing more than one string, i.e. yymm.  I have added further lines in there to look for just dd and replace with !dd! but in this case it then found "TestDddmmyy" and replaced the first two Dd with the day..


Steve

Today is 20 12 08 17
The new name for Test Ayymmdd.doc is Test A120817.doc
The new name for Test Bccyymmdd.doc is Test B20120817.doc
The new name for Test Cmmdd.doc is Test C0817.doc
The new name for Test Dyymm.doc is Test D1208.doc
The new name for Test Dddmmyy.doc is Test 17d0812.doc
Press any key to continue . . .

@echo off
setlocal enabledelayedexpansion
echo wscript.echo left(year(date),2) ^& "," ^& right(year(date),2) ^& "," ^& right(100 + month(date),2) ^& "," ^& right(100+day

(date),2)  > "%temp%\dateparts.vbs"
for /f "tokens=1-4 delims=," %%a in ('cscript //nologo "%temp%\dateparts.vbs"') do (set cc=%%a)&(set yy=%%b)&(set mm=%%c)&(set dd=%

%d)

echo Today is %cc% %yy% %mm% %dd%

call :Test "Test Ayymmdd.doc"
call :Test "Test Bccyymmdd.doc"
call :Test "Test Cmmdd.doc"
call :Test "Test Dyymm.doc"
call :Test "Test Dddmmyy.doc"

pause

exit /b

:Test
set myfilename=%~1
set myfilename=%myfilename:ccyymmdd=!cc!!yy!!mm!!dd!%
set myfilename=%myfilename:yymmdd=!yy!!mm!!dd!%
set myfilename=%myfilename:yymm=!yy!!mm!%
set myfilename=%myfilename:mmdd=!mm!!dd!%
set myfilename=%myfilename:mm=!mm!%
set myfilename=%myfilename:dd=!dd!%
set myfilename=%myfilename:yy=!yy!%
set myfilename=%myfilename:cc=!cc!%
echo The new name for %~1 is %myfilename%

exit /b

Open in new window

0
Veeam and MySQL: How to Perform Backup & Recovery

MySQL and the MariaDB variant are among the most used databases in Linux environments, and many critical applications support their data on them. Watch this recorded webinar to find out how Veeam Backup & Replication allows you to get consistent backups of MySQL databases.

 
LVL 43

Expert Comment

by:Steve Knight
ID: 38306492
BTW the key bit here is the "setlocal enabledelayedexpansion"

that means that the using !variable! is not evaluated until the code runs that line... so in this case it evaluates the !cc! to the right century then uses that in the rest of the line.

Otherwise if we just used %filename:cc=%cc%% it just doesn't work properly...

Today is 20 12 08 17
The new name for Test Ayymmdd.doc is Test A.do%y%m%d%y%m%d%y%m%m%d%m%d%y%c%
The new name for Test Bccyymmdd.doc is Test B.do%y%m%d%y%m%d%y%m%m%d%m%d%y%c%
The new name for Test Cmmdd.doc is Test C.do%y%m%d%y%m%d%y%m%m%d%m%d%y%c%
The new name for Test Dyymm.doc is Test D.do%y%m%d%y%m%d%y%m%m%d%m%d%y%c%
The new name for Test Dddmmyy.doc is Test d.do%y%m%d%y%m%d%y%m%m%d%m%d%y%c%
0
 
LVL 71

Expert Comment

by:Qlemo
ID: 38307906
Steve,

I've verified the case insensitive string replace issue - strange, I never was aware of that!

However, I think you got the subject wrong. The format template is coming in as a separate value, and the result needs to be applied to a bunch of file names. The file names do not contain the formatting stuff.
That does not change much, as the only additional step to take would be to set up another replacement operation for (e.g.) !filename!. If we do that as last replacement step, no potential conflicts of template characters in the file name can occur.
0
 
LVL 43

Expert Comment

by:Steve Knight
ID: 38308488
Hmm, might be right there Qlemo but not how I read it?  Will see what comes back and one of us can soon shift things around if needed.

Steve
0
 
LVL 71

Expert Comment

by:Qlemo
ID: 38308522
If I'm correct, then applying my thoughts to the code given results in (I've removed the code retrieving the date parts, as that is done already somewhere else according to the OP):
@echo off
setlocal enabledelayedexpansion

call :Test "Test Ayymmdd.doc"
call :Test "Test Bccyymmdd.doc"
call :Test "Test Cmmdd.doc"
call :Test "Test Dyymm.doc"
call :Test "Test Dddmmyy.doc"

pause

exit /b

:Test
set myfilename=%~1
set mask=%~2
set mask=%mask:ccyymmdd=!cc!!yy!!mm!!dd!%
set mask=%mask:yymmdd=!yy!!mm!!dd!%
set mask=%mask:yymm=!yy!!mm!%
set mask=%mask:mmdd=!mm!!dd!%
set mask=%mask:mm=!mm!%
set mask=%mask:dd=!dd!%
set mask=%mask:yy=!yy!%
set mask=%mask:cc=!cc!%
set myfilename=%mask:filename=!myfilename!%
echo The new name for %~1 with format %~2 is %myfilename%
exit /b

Open in new window

0
 

Author Comment

by:jennifer_EDI_Gal
ID: 38311344
Thanks!,
Actually you are right the format will be comming in as part of the filename, not as a seperate value passed in a parameter. it is a little less elegant than i thought it could be, but it really does not matter because there are only a finite set of combinations possible. if i get too "granular" (i hate buzzwords) then stuff like "CCsPizzaCCYYMM.pgp" could be a problem :P so i will look for the entire date structure.

Thanks again for all your help,
Jen
0
 
LVL 71

Expert Comment

by:Qlemo
ID: 38311383
"CCsPizzaCCYYMM.pgp" is a problem. Both CCYYMM and CC are found and replaced ... You will most likely have to remove
set myfilename=%myfilename:mm=!mm!%
set myfilename=%myfilename:dd=!dd!%
set myfilename=%myfilename:yy=!yy!%
set myfilename=%myfilename:cc=!cc!%

Open in new window

as that is too ambigious.
0
 

Author Comment

by:jennifer_EDI_Gal
ID: 38311451
You are correct,

Yes I couls see that, hence teh CC's Pizza example, i think MMCandy would be an issue too :D I will only be searching for complete valid formats, not just the characters 'cc' or 'yy' etc....

Thanks once again,
Jen
0
 

Author Comment

by:jennifer_EDI_Gal
ID: 38312120
BTW - Here is the final little piece of code (there were only five variations in the current list) the variables %mm%, %dd% and etc... were set in an init vars section :

REM ::==================================================================
REM :: RENAME FILE IF NECESSARY
REM ::==================================================================

:RENAME

IF %INPUT_FILE%==%OUTPUT_FILE% GOTO :NO_RENAME

setlocal enabledelayedexpansion

SET OUTPUT_FILE=%OUTPUT_FILE:ccyymmdd=!cc!!yy!!mm!!dd!%
SET OUTPUT_FILE=%OUTPUT_FILE:ccyymm=!cc!!yy!!mm!%
SET OUTPUT_FILE=%OUTPUT_FILE:yymmdd=!yy!!mm!!dd!%
SET OUTPUT_FILE=%OUTPUT_FILE:yymm=!yy!!mm!%
SET OUTPUT_FILE=%OUTPUT_FILE:mmdd=!mm!!dd!%

:NO_RENAME

IF %DO_WE_ENCRYPT%==%YES% GOTO :CRYPTO_STUFF

REM ::==================================================================
for grins (and for any other poor person who ever needs to do this)  here is how i set up the date time stuff:

REM ::==================================================================
REM ::= setup date and time variables so we can time stamp stuff                                    =
REM ::==================================================================

REM :: set date_string = system date
for /f "tokens=1-5 delims=/ " %%d in ("%date%") do set date_string=%%g%%e%%f
if not %errorlevel%==0 goto :ERROR_1

REM :: set time_string  
for /f "tokens=1-5 delims=:" %%d in ("%time%") do set time_string=%%d-%%e
if not %errorlevel%==0 goto :ERROR_1


REM :: Parse Date And Time into Variables to use when renaming files

set cc=%date_string:~0,2%
set yy=%date_string:~2,2%
set mm=%date_string:~4,2%
set dd=%date_string:~6,2%
set my_month=%date_string:~4,2%
set hh=%time_string:~0,2%
set mn=%time_string:~3,2%
if not %errorlevel%==0 goto :ERROR_1

REM :: echo %cc% %yy% %mm% %dd% %hh% %mn%
0
 
LVL 43

Expert Comment

by:Steve Knight
ID: 38312171
I'm sure you are aware of them but the issues with getting date / time by using %date% and %time%, if you, for instance run the batch on a different pc, os, user, scheduled it etc. then you could have a dozen different date formats, leading zeroes, different order, day name at the front, or not etc.

Anyway that's why I use VBscript, or WMIC methods hence my article I quoted... hmm or actually looks like I posted link to an earlier Q by mistake before, sorry.

http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/MS_DOS/A_1153-Using-dates-in-batch-files-scripts.html

Steve
0
 

Author Comment

by:jennifer_EDI_Gal
ID: 38312247
Thanks Steve,

Fortunately I own the server, which is brand spanking new, that this will be running on and can control how the date is formatted. One of the few things that i can control in this environment. So it should not be a concern for the next couple of years.

Hummmm come to think of it I remember writing code in the early eighties saying that this thing will have issues in the year 2000 but heck it will not be around then, I actually got paid to fix it 15 years later:)

In this case it is only temporary, scheduled to be replaced by real middleware within the next couple of years so it should be fine as the stop gap solution it is intended to be.

Jen
0
 
LVL 43

Expert Comment

by:Steve Knight
ID: 38312268
Ok, well ask if you need any other help here otherwise look forward to getting a "good answer"!
0
 

Author Comment

by:jennifer_EDI_Gal
ID: 38312298
BTW Guys, this is my first experience with "Experts Exchange". I am blown away by the rapid responses I have received and the thoughtful solutions suggested. Kudos to all of you for taking your time to help those with questions like mine.
0
 
LVL 43

Expert Comment

by:Steve Knight
ID: 38312338
No problem and glad it has been useful - have learned a lot here myself over the years.

You will find "Accept as answer" and "accept multiple answer" buttons / links there somewhere (I don;t use that side much!)

Steve
0
 

Author Comment

by:jennifer_EDI_Gal
ID: 38312350
Thanks Again, Jen
0
 

Author Comment

by:jennifer_EDI_Gal
ID: 38313079
Thanks!
0

Featured Post

Get quick recovery of individual SharePoint items

Free tool – Veeam Explorer for Microsoft SharePoint, enables fast, easy restores of SharePoint sites, documents, libraries and lists — all with no agents to manage and no additional licenses to buy.

Question has a verified solution.

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

This is about my first experience with programming Arduino.
When you discover the power of the R programming language, you are going to wonder how you ever lived without it! Learn why the language merits a place in your programming arsenal.
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…
Six Sigma Control Plans

850 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