?
Solved

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

Posted on 2011-05-10
8
Medium Priority
?
2,146 Views
Last Modified: 2012-05-11
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

0
Comment
Question by:wp179787
8 Comments
 
LVL 85

Accepted Solution

by:
oBdA earned 2000 total points
ID: 35727541
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 35727837

: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
 

Author Closing Comment

by:wp179787
ID: 35727860
Excellent, thanks
0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 
LVL 10

Expert Comment

by:ReneGe
ID: 35727861
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 35727872
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 35727883
Please disregard my prevous post as like oBdA shared, delayedexpansion must be set, and other considerations.
0
 
LVL 10

Expert Comment

by:ReneGe
ID: 35727913
Glad I could help.
No points?
0
 
LVL 59

Expert Comment

by:Bill Prew
ID: 35732056
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

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

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

The following is a collection of cases for strange behaviour when using advanced techniques in DOS batch files. You should have some basic experience in batch "programming", as I'm assuming some knowledge and not further explain the basics. For some…
Introduction: Recently, I got a requirement to zip all files individually with batch file script in Windows OS. I don't know much about scripting, but I searched Google and found a lot of examples and websites to complete my task. Finally, I was ab…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses

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