-1

I have videos files with filenames:

Series.Name.S01E01.andalotofstuff.mkv
Series.Name.S01E02.andalotofstuff.mkv
Series.Name.S02E01.andalotofstuff.mkv
etc.

where andalotofstuff is not necessarily the same in each file, and can include ., - and [].

I also have subtitles files with filenames:

Series Name 1x01 - Episode Name andotherstuff.srt
Series Name 1x02 - Episode Name andotherstuff.srt
Series Name 2x01 - Episode Name andotherstuff.srt
etc.

where andotherstuff is not necessarily the same in each file, and can include ().

What i want is to rename srt files with the corresponding mkv filename with a batch script, if possible, and i have no idea how.

Some real examples are:

Marvels.Agents.of.S.H.I.E.L.D.S05E04.720p.HDTV.x264-AVS[eztv].mkv
Marvel's Agents of S.H.I.E.L.D. 5x04 - A Life Earned (Español (Latinoamérica)).srt

The.Shannara.Chronicles.S02E08.720p.HDTV.x264-AVS[eztv].mkv
The Shannara Chronicles 2x08 - Amberle (Español (España)).srt

The.Shannara.Chronicles.S02E10.720p.HDTV.x264-KILLERS[eztv].mkv
The Shannara Chronicles 2x10 - Blood (English).srt

Note that not necessarily all video files has a corresponding subtitle file.

Here i found something that is supposed to work on linux...

kurokirasama
  • 737
  • 8
  • 31

2 Answers2

2

Here is a commented batch file for this task:

@echo off

rem Setup a local environment for this batch file creating lots
rem of environment variables which should not exist anymore after
rem finishing batch file execution.

setlocal EnableExtensions DisableDelayedExpansion

rem Get all *.mkv and *.srt file names in current directory without path
rem and without file extension loaded into memory assigned to environment
rem variables with name mkv_1, mkv_2, ..., srt_1, srt_2, ... using the
rem two subroutines GetFileList and AddFileToList.

call :GetFileList mkv
call :GetFileList srt
goto ValidateFileCounts

rem Subroutine GetFileList runs command FOR which executes command DIR in
rem a separate command process in background which outputs all file names
rem with the file extension passed to the subroutine as first parameter
rem sorted by name. Each file name output by DIR is assigned to an environment
rem variable with passed file extension, an underscore and an incremented
rem number as variable name. The number of files with given file extension
rem is assigned to an environment variable with name FileCount_Extension.

:GetFileList
set "FileNumber=0"
set "FileExtension=%1"
for /F "delims=" %%I in ('dir *.%FileExtension% /A-D /B /ON 2^>nul') do call :AddFileToList "%%~nI"
set "FileCount_%FileExtension%=%FileNumber%"
goto :EOF

rem Subroutine AddFileToList increments current file number by one and then
rem assigns the file name without file extension and without path passed
rem from calling subroutine GetFileList as first and only parameter to
rem an environment variable with automatically generated varible name.

:AddFileToList
set /A FileNumber+=1
set "%FileExtension%_%FileNumber%=%~1"
goto :EOF

rem After creating the two file lists in memory it is validated that the
rem file rename operation can be started at all. There must be *.srt files
rem found in current directory and the number of *.mkv files must be equal
rem the number of *.srt files.

:ValidateFileCounts
if %FileCount_srt% == 0 (
    echo/
    echo There are no *.srt files in directory:
    echo/
    echo %CD%
    echo/
    pause
    goto EndBatch
)

if not %FileCount_mkv% == %FileCount_srt% (
    echo/
    echo Number of *.mkv files is not equal number of *.srt files in directory:
    echo/
    echo %CD%
    echo/
    pause
    goto EndBatch
)

rem Now delayed environment variable expansion is needed for the file rename
rem operation in a loop which could not be enabled at beginning of the batch
rem file in case of any file name contains one or more exclamation marks.

rem *.srt files having already the same file name as corresponding *.mkv
rem file detected by identical current and new file name are ignored for
rem the rename operation.

rem It is also not possible to rename a *.srt file to name of a *.srt which
rem already exists. In this case an error message is output for the *.srt
rem file which cannot be renamed and finally PAUSE is executed to give the
rem batch file user the possibility to read all those file rename errors.
rem But it is very unlikely that this error message is displayed ever.

setlocal EnableDelayedExpansion
set "RenameError="
for /L %%I in (1,1,%FileCount_srt%) do (
    set "FileNameNew=!mkv_%%I!.srt"
    set "FileNameNow=!srt_%%I!.srt"
    if not "!FileNameNew!" == "!FileNameNow!" (
        if not exist "!FileNameNew!" (
            ren "!FileNameNow!" "!FileNameNew!"
        ) else (
            echo Rename file !FileNameNow!
            echo to new name !FileNameNew!
            echo not possible as such a file exists already.
            echo/
            set "RenameError=1"
        )
    )
)
if defined RenameError pause
endlocal

rem The previous environment is restored finally which means all environment
rem variables created by this batch file are removed from memory. There is
rem neither a message output nor batch file processing halted if no error
rem occurred during entire process.

:EndBatch
endlocal

There is no real file name matching algorithm used as it looks like the algorithm is human language intelligence. So the batch file just loads into memory the list of *.mkv file names sorted by name and the list of *.srt file names also sorted by name and then renames first *.srt file to name of first *.mkv file, second *.srt file to name of second *.mkv file, and so on. This simple solution worked for the given examples.

It is possible to insert the command echo left to command ren and append command pause at end of the batch file or run it from within a command prompt window to see all the file rename operations without really doing them for verification by user before really renaming the *.srt files.

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

  • call /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • rem /?
  • ren /?
  • setlocal /?

Read also the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.

Read this answer for details about the commands SETLOCAL and ENDLOCAL and Where does GOTO :EOF return to?

Mofi
  • 46,139
  • 17
  • 80
  • 143
0

In Windows you can do it with program called "Subtitle And Video Renamer". I just tested version 0.5.1 and I renamed ~30 subtitles with 2 buttons click.

crisc2000
  • 1,082
  • 13
  • 19