Search code examples
batch-filerenamebatch-rename

Batch rename to numeric names with leading zeroes


So I'm trying to write a batch that renames <randomname>.EPL to fbXYZ.EPL (XYZ - number with leading zeroes)

So something like bes_rush.EPL should turn into fb001.EPL and other files should get renamed too (fb002.EPL, fb003.EPL, etc.)

Here's what I have so far

setlocal ENABLEDELAYEDEXPANSION
set/a fileNum = 0
set fileNum=0000%fileNum%
set fileNum=%fileNum:~-3%

for %%f in (*.EPL) do (
  ren %%~nf%%~xf fb!fileNum!%%~xf
  set/a fileNum += 1
)

I can make it rename numerically and it actually works but I can't add the leading zeroes at all, all my attempts lead to it renaming only one file and leaving the rest


Solution

  • The following would be my suggestion:

    Please note however, that the example does not cater for any existing filenames in the directory which already match fb<num><num><num>.EPL, so those will also be renamed with possible new numbers too.

    @Echo Off
    SetLocal EnableExtensions DisableDelayedExpansion
    Set "SourceDir=."
    Set "FileGlob=*.EPL"
    Set "Prefix=fb"
    Set "FileNum=1000"
    For /F Delims^= %%G In ('(Set PATHEXT^=^) ^& "%SystemRoot%\System32\where.exe"
     /F "%SourceDir%":"%FileGlob%" 2^> NUL') Do (Set /A FileNum += 1
        SetLocal EnableDelayedExpansion & Ren %%G "%Prefix%!FileNum:~-3!%%~xG"
        EndLocal)
    
    • Insert your required source directory between the = and closing " on line 3, (I've used . for the current directory, as per your example, but you can use an absolute or other relative path as needed).
    • Insert your required file glob prefix string between the = and closing " on line 4, (I've used *.EPL to match your example).
    • Insert your required file name prefix string between the = and closing " on line 5, (I've used fb to match your example).

    I've used 1000 as your starting file number, because Set /A uses integers, and sees multiple concurrent 0's as just 0. Adding the 1 will prevent that, and will be omitted, when the varible expansion, uses just the last three characters. I also adjusted it so that the file numbering begins with fb001.EPL, to match your question parameters, (your code was beginning the sequence with fb000.EPL).

    I've enabled delayed expansion within the loop, because it is required, when both modifying and using a variable within the same parenthesized code block. It shouldn't normally be enabled for the entire script, because filenames and strings containing ! characters can be affected, (those characters will be omitted).

    I've also gone 'belt and braces' with the file selection, by using where.exe. This utility is not affected by Windows using 8.3 naming, which, whilst it may not be an issue with your provided example, will match exactly extensions .EPL, not those which begin with .EPL. Standard For loops, (which you used), and the more commonly used Dir command are both affected by 8.3 naming.

    For additional robustness, I've used the full path to where.exe with the system environment variable %SystemRoot%, to prevent reliance on the %Path% variable which is often broken, by its incorrect or accidental end user modification.


    As a direct resolution to your own code without modification to the majority of it:

    setlocal ENABLEDELAYEDEXPANSION
    set /a fileNum = 1
    set fileNum=1000%fileNum%
    
    for %%f in (*.EPL) do (
      ren "%%f" fb!fileNum:~-3!%%~xf
      set /a fileNum += 1
    )
    

    I must add however, that's because your example code is using a standard for loop, you may have issues. The problem is that a your loop will pass the first file through to the do portion whilst it is still parsing the others under the all encompassing * glob. This means that fb001.EPL will be put back into the list for parsing, and could be picked up again for processing another time, this could continue for other files too!