This is an example on how to split a file name on first hyphen character.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /R %%A in (*.mkv *.avi *.mp4) do (
for /F "eol=| tokens=1* delims=-" %%B in ("%%~nA") do (
set "Artist=%%B"
set "Title=%%C"
setlocal EnableDelayedExpansion
if "!Artist:~-1!" == " " set "Artist=!Artist:~0,-1!"
if defined Title if "!Title:~0,1!" == " " set "Title=!Title:~1!"
echo Artist=!Artist!
if defined Title (echo Title=!Title!) else echo %%~na has no title.
endlocal
)
)
endlocal
The outer FOR loop searches recursive in current directory and all subdirectories for non-hidden files with file extension mkv
, avi
or mp4
and assigns the full qualified file name (file path + file name + file extension) of a found file to loop variable A
.
The inner FOR loop interprets just the file name without path and file extension as string to process.
The end of line character is redefined from default ;
which can be at beginning of a file name to |
which no file name can ever contain to avoid that a file name starting by chance with a semicolon is ignored by the inner FOR loop.
By default FOR with option /F
processing a double quoted string splits up the string into substrings using normal space and horizontal tab as string delimiters and assigns just first space/tab separated string to the specified loop variable. This string splitting behavior is modified with tokens=1* delims=-
to split the file name string on hyphens instead of spaces/tabs with ignoring hyphens at beginning of file name and assigning the string up to first hyphen inside the file name to specified loop variable B
and everything after first (sequence of) hyphen(s) to next loop variable according to ASCII table without any further string splitting which is loop variable C
.
In other words on a file name like Artist - title
the string Artist
with a space at end is assigned to loop variable B
and the string title
with a space at beginning is assigned to loop variable C
. The two unwanted spaces need to be removed. This can be done using string substitution. But this must be done using delayed expansion not yet enabled because of file names containing an exclamation mark should be also processed correct. For that reason delayed environment variable expansion is next enabled inside the inner FOR loop.
The first IF condition checks if last character of artist string is really a space character and runs the string substitution to remove this space at end of artist string if this condition is true.
The second IF condition first checks if an environment variable Title
is defined at all because of the commands of inner FOR loop are also executed on file name does not contain a hyphen at all in which case %%C
expands to an empty string and so environment variable Title
is deleted from list of environment variables.
The nested third IF condition checks if first character of value of defined environment variable Title
is a space and runs the string substitution to redefine Title
without first character if this condition is true.
Now artist and title strings can be output before delayed expansion is disabled again by restoring previous environment. Please read this answer for details about the commands SETLOCAL and ENDLOCAL and what exactly happens on each execution of SETLOCAL and ENDLOCAL because of there is much more done than just enabling and disabling delayed environment variable expansion on each found file name.
Note: The title part can contain also the character sequence space, hyphen, space as well as one or more hyphens, but of course the artist string should not contain a hyphen as this character is interpreted as separator between artist and title independent on spaces existing around the hyphen or not. Windows command processor is not designed for enhanced string manipulations like other script interpreters. A different code would be necessary if the condition for splitting file name in artist and title must be space, hyphen, space and not just hyphen.
Other batch file code using -
to split file name into artist and title strings:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /R %%A in (*.mkv *.avi *.mp4) do call :ProcessFileName "%%~nA"
endlocal
goto :EOF
:ProcessFileName
set "FileName=%~1"
set "Title=%FileName:* - =%"
setlocal EnableDelayedExpansion
set "Artist=!FileName: - %Title%=!"
echo Artist=!Artist!
echo Title=!Title!
endlocal
goto :EOF
But this solution using just string substitutions in a subroutine does not work on title string containing an equal sign used as delimiter on string substitution. It is also much slower in comparison to above batch file solution on processing a large amount of file names.
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 /?
echo /?
endlocal /?
for /?
goto /?
if /?
set /?
setlocal /?
See also Where does GOTO :EOF return to?