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

wp179787Asked:
Who is Participating?
 
oBdACommented:
You need to enable the delayed expansion of ennvironment variables (which you did) and use "!" instead of "%" to expand variables (other than loop variables) where required.
The issue is described pretty well in "help set".
Regular expansion in the loop with "%":
@echo off
setLocal EnableDelayedExpansion
set Count=0
for /l %%i in (1, 1, 10) do (
  echo Count in loop: %Count%
  set /a Count += 1
)
echo Count after loop: %Count%

Open in new window

Delayed expansion in the loop with "!":
@echo off
setLocal EnableDelayedExpansion
set Count=0
for /l %%i in (1, 1, 10) do (
  echo Count in loop: !Count!
  set /a Count += 1
)
echo Count after loop: %Count%

Open in new window

0
 
ReneGeCommented:

: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

0
 
wp179787Author Commented:
Excellent, thanks
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

 
ReneGeCommented:
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
0
 
ReneGeCommented:
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
0
 
ReneGeCommented:
Please disregard my prevous post as like oBdA shared, delayedexpansion must be set, and other considerations.
0
 
ReneGeCommented:
Glad I could help.
No points?
0
 
Bill PrewCommented:
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
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.