Justin
Justin

Reputation: 1

Batch renaming files incrementally with special characters

I am trying to rename the episodes in a directory in an incremental way, but there are exclamation marks in some of the episodes. It will skip those files. I tried doing delayed expansion, but it didn't work.

@echo off
setlocal DisableDelayedExpansion

  set /a num=0
  for %%a in (*.mkv) do (
  set filename=%%a
  setlocal EnableDelayedExpansion
  ren "!filename!" "Soul Eater Episode 0!num!.mkv"
  set /a num=!num!+1
 )
pause
endlocal

Upvotes: 0

Views: 246

Answers (2)

Mofi
Mofi

Reputation: 49086

The following batch file code could be used to rename the files containing one or more ! in file name.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "num=0"
for /F "eol=| delims=" %%I in ('dir *.mkv /A-D /B /ON 2^>nul ^| %SystemRoot%\System32\findstr.exe /B /I /L /V /C:"Soul Eater Episode"') do (
    set "filename=%%I"
    setlocal EnableDelayedExpansion
    ren "!filename!" "Soul Eater Episode 0!num!.mkv"
    endlocal
    set /A num+=1
)
pause
endlocal

There is no need to use an arithmetic expression to define the environment variable num with the value 0.

It is very advisable on running renames on a list of file names in a directory using a wildcard pattern like *.mkv to get first the list of file names loaded into memory of Windows command processor and then rename one file after the other as done by this code using a for /F loop. Otherwise the result of the file renames is unpredictable as depending on file system (NTFS, FAT32, exFAT) and current names of the files matched by the wildcard pattern.

The additional FINDSTR is used to filter out all file names beginning already case-insensitive with the string Soul Eater Episode although the batch file would most likely fail to rename some files if there are already files with a file name matched by Soul Eater Episode 0*.mkv in the current directory on execution of the batch file.

Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul and |. The redirection operators > and | must be escaped with caret character ^ on FOR command line to be interpreted as literal characters when Windows command interpreter processes this command line before executing command FOR which executes the embedded command line with dir and findstr with using a separate command process started in background with %ComSpec% /c and the specified command line appended as additional arguments.

The file name is first assigned as output by DIR filtered by FINDSTR to the environment variable filename with delayed expansion disabled as otherwise the double processing of this command line on enabled delayed expansion would result in interpreting ! in file name assigned to loop variable I as beginning/end of a delayed expanded environment variable reference.

Then delayed expansion is enabled to be able to do the rename with referencing the environment variable num using delayed expansion and of course also the file name assigned to environment variable filename.

Next delayed expansion is disabled again before an arithmetic expression is used using the preferred syntax to increment the value of an environment variable by one which always works independent on disabled or enabled delayed expansion.

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • pause /?
  • ren /?
  • set /?
  • setlocal /?

Please read this answer with details on what happens in background on every execution of SETLOCAL and ENDLOCAL.

Upvotes: 0

Try this:

@echo off
setlocal EnableDelayedExpansion
  set /a num=0
  for %%a in (*.mkv) do (
  set filename=%%a
  ren "!filename!" "Soul Eater Episode 0!num!.mkv"
  set /a num=!num!+1
 )
endlocal
pause

Upvotes: 0

Related Questions