Link to home
Start Free TrialLog in
Avatar of wp179787
wp179787

asked on

How do I run string manipulation within a FOR loop in a DOS batch script

Hello,

I have compiled a batch script to amongst other things, rename a list of files, but am having problems with string manipulation within a FOR loop.  At the moment it copies the name of the files into a temporary file (TempFileNames.###) and then into a FOR loop for renaming by adding the date & time.  That works O.K but I'm really struggling to remove the first .csv

e.g. Test1.csv becomes Test1.csv_10052011__10_35.csv whereas I would like it to become Test1_10052011__10_35.csv

I can strip the .csv using 'SET REMOVEFILEXT=%REMOVEFILEXT:.csv=%' however I can't get it to work within the FOR loop, as REMOVEFILEXT remains the same and it only works for the first file.

Obviously it still works as it ends .csv but I'm trying to neaten it up.

I'm sure it's relatively easy for an expert who can point me in the right direction
Thanks!
:MULTIPLE
DIR /B *.csv > TempFileNames.###

@echo off
setLocal EnableDelayedExpansion

for /f "tokens=* delims= " %%a in (TempFileNames.###) do (
REN %%a %%a_%DATE:/=%__%TIMESTAMP:/=%.csv
)
GOTO FILEMOVEANDARCHIVE

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of oBdA
oBdA

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

:MULTIPLE
@ECHO OFF

CALL :GetDateTime

FOR /f "delims=" %%a in ('DIR /B *.csv') do (
REN %%a %%~na_%TheDate%__%TheTime%.csv
)

GOTO FILEMOVEANDARCHIVE

:GetDateTime
REM READ DATE
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
	IF %%A GTR 0 (
	SET DayVal=%%A
	SET HourVal=%%B
	SET MinVal=%%C
	SET MonthVal=%%D
	SET SecVal=%%E
	SET YearVal=%%F
	)
)

REM ADDING LEADING "0"
	IF %DayVal% LSS 10   (SET Day=0%DayVal%) 		ELSE (SET Day=%DayVal%)
	IF %HourVal% LSS 10  (SET Hour=0%HourVal%) 		ELSE (SET Hour=%HourVal%)
	IF %MinVal% LSS 10   (SET Min=0%MinVal%) 		ELSE (SET Min=%MinVal%)
	IF %MonthVal% LSS 10 (SET Month=0%MonthVal%) 	ELSE (SET Month=%MonthVal%)
	IF %SecVal% LSS 10   (SET Sec=0%SecVal%) 		ELSE (SET Sec=%SecVal%)
	SET Year=%YearVal%

	SET TheDate=%Year%-%Month%-%Day%
	REM SET TheTime=%Hour%.%Min%.%Sec%
	SET TheTime=%Hour%_%Min%


EXIT /b

Open in new window

Avatar of wp179787
wp179787

ASKER

Excellent, thanks
Instead of renaming the files then move them, you could also just move them with a new name.

Something like:
Move file.csv C:\Backup\1_2011-05-10__07_09.csv
And last, by using your script and just fixing what you asked, change:

REN %%a %%a_%DATE:/=%__%TIMESTAMP:/=%.csv
to
REN %%a %%~na_%DATE:/=%__%TIMESTAMP:/=%.csv
Please disregard my prevous post as like oBdA shared, delayedexpansion must be set, and other considerations.
Glad I could help.
No points?
For what it's worth, I don't think there is a simpler and more efficient way to handle this.  First, you don't need to get a list of the files into a temp file and then read it, there is a flavor of the FOR loop that will return the file names directly to the loop.  In addition, the loop variables, like %%A have modifiers that allow you to refer to sub pieces of the file name, for example %%~nA is just the file name, and %%~xA is just the extension.  DO FOR /HELP and read up on the various options, there is a lot of power there.

So I think you can do it all in basically one line like this.  I assumed the labels were still needed...

@echo off
:MULTIPLE
for %%A in ("*.csv") do ren "%%~A" "%%~nA_%DATE:/=%__%TIMESTAMP:/=%.csv"
GOTO FILEMOVEANDARCHIVE

Open in new window

~bp