Reputation: 2629
I have a batch file which unzips archives from within a directory, and renames the extracted files. The contents of my batch file are:
for /F %%I IN ('dir /b /s *.zip *.rar') DO (
"C:\Program Files\7-Zip\7z.exe" x -o"%%~dpI" "%%I" -aoa
)
DEL *.zip
@echo off
set i=1
for %%f in (*.xml) do call :renameit "%%f"
goto done
:renameit
ren %1 FileName%i%_Msd.xml
set /A i+=1
:done
I expect the files to be renamed as
FileName1.xml
FileName2.xml
FileName3.xml
...
However, the renamed file names seem to start from 2 instead of 1. If I re-run the batch file after it has initially extracted and incorrectly renamed starting from 2, it corrects this naming error and starts from one.
How can I correct this so as the renamed files correctly start from 1?
Upvotes: 0
Views: 3018
Reputation: 14290
An explanation for you and if you would have watched your CODE execute you would have seen this PLAIN as day.
The FOR command is iterating the files in the current folder one file at a time. So for example if you have three files in your folder named A.txt, B.txt and Z.txt, the FOR command first processes A.txt and renames it to File1.txt. It then sees B.txt because it is the next file alphabetically and renames it to File2.txt. Now because you renamed A.txt to File1.txt, it sees this file next and renames it to File3.txt. After that it sees Z.txt and renames it too File4.txt. So the problem is not with your counter variable, it is how the FOR command processes the files in the folder.
Now if you test this code.
@echo off
dir /b *.txt
set i=1
for %%f in (*.txt) do call :renameit "%%f"
pause
GOTO :EOF
:renameit
@ECHO ON
ren %1 FileName%i%.txt
@ECHO OFF
set /A i+=1
Your output will look like this.
A.txt
B.txt
Z.txt
C:\test>ren "A.txt" FileName1.txt
C:\test>ren "B.txt" FileName2.txt
C:\test>ren "FileName1.txt" FileName3.txt
C:\test>ren "Z.txt" FileName4.txt
Press any key to continue . . .
Now if you change to using a FOR /F command to parse the output of the DIR command, you will get your desired result. The DIR command will do all of its processing first before the FOR command takes over and start processing the output.
So changing the code:
@echo off
dir /b *.txt
set i=1
for /F "delims=" %%f in ('dir /a-d /b *.txt') do call :renameit "%%f"
pause
GOTO :EOF
:renameit
@ECHO ON
ren %1 FileName%i%.txt
@ECHO OFF
set /A i+=1
Your output will now be this.
A.txt
B.txt
Z.txt
C:\test>ren "A.txt" FileName1.txt
C:\test>ren "B.txt" FileName2.txt
C:\test>ren "Z.txt" FileName3.txt
Press any key to continue . . .
Upvotes: 2