如何用分隔符“-”分割文件名并在前后回显部分

时间:2019-03-04 01:33:41

标签: batch-file split

我需要帮助将文件名或文件夹名称分成2部分。 子文件夹中的所有文件始终使用相同的命名惯例: (主文件夹/ 艺术家-标题 / 艺术家-标题 .ext)。

我开始创建一个批处理,该批处理为视频文件写入.nfo文件(递归)。 一切工作正常,我只是找不到一种方法在“ delimeter =-”之前和之后加上 part2(title) part1(artist)。 / p>

这是我现在拥有的:

@echo off
TITLE NFO creator Musicvideos
COLOR B
ECHO -------------------------------------------------------------------------
ECHO  Create NFO for Musicvideos, all existing will be overwritten
ECHO  Push key to Start
ECHO -------------------------------------------------------------------------
ECHO.
PAUSE > NUL
REM Ende Header
for /r %%a in (*.mkv *.avi *.mp4) do (
(
echo ^<?xml version="1.0" encoding="UTF-8" standalone="yes"?^>
echo ^<musicvideo^>
for %%b in ("%%~na") do echo ^  ^<title^>%%~b^</title^>
echo ^  ^<^!-- start test set attributes --^>
for %%b in ("%%~na") do echo ^  ^<path^>%~dp0^</path^>
for %%b in ("%%~na") do echo ^  ^<name^>%%~na^</name^>
for %%b in ("%%~na") do echo ^  ^<filenameandpath^>%%~a^</filenameandpath^>
for %%b in ("%%~na") do echo ^  ^<basepath^>%%~a^</basepath^>
for %%b in ("%%~na") do echo ^  ^<before^>^</before^>
REM for "tokens=1,2 delims= - " %%b  in ("%%~na") do (
REM echo ^  ^<before^>^%%a</before^>
REM echo ^  ^<after^>^%%b</after^>
REM )
REM test end
echo ^  ^<rating^>^0.000000^</rating^>
echo ^  ^<userrating^>^8^</userrating^>
echo ^  ^<epbookmark^>^0.000000^</epbookmark^>
echo ^  ^<year^>^</year^>
echo ^  ^<track^>^-1^</track^>
echo ^  ^<album^>^</album^>
echo ^  ^<artist^>^</artist^>
echo ^  ^<genre^>^</genre^> 
echo ^  ^<outline^>^</outline^>
echo ^  ^<plot^>^</plot^>
echo ^  ^<tagline^>^</tagline^>
echo ^  ^<thumb^>^</thumb^>
echo ^  ^<status^>^</status^>
echo ^  ^<studio^>^</studio^>
echo ^  ^<art^>
echo ^      ^<fanart^>%~dp0^%%~na^-fanart.jpg^</fanart^>
echo ^      ^<poster^>%~dp0^%%~na^-poster.jpg^</poster^>
echo ^      ^<artistthumb^>%~dp0^%%~na^-artistthumb.jpg^</artistthumb^>
echo ^      ^<banner^>%~dp0^%%~na^-banner.jpg^</banner^>
echo ^      ^<clearlogo^>%~dp0^%%~na^-clearlogo.png^</clearlogo^>
echo ^      ^<discart^>%~dp0^%%~na^-discart.png^</discart^>
echo ^      ^<landscape^>%~dp0^%%~na^-landscape.jpg^</landscape^>
echo ^  ^</art^>
echo ^</musicvideo^>
)>"%%~dpna.nfo"
)
ECHO.
ECHO Creatin is done
ECHO Push key to exit
ECHO.
PAUSE > NUL

4 个答案:

答案 0 :(得分:2)

这是我要这样做的方式:

@echo off
setlocal
for /R %%A in (*.mkv *.avi *.mp4) do call :SplitFileName "%%~nA"
goto :EOF

:SplitFileName
set "FileName=%~1"
set "Title=%FileName: - =" & set "Artist=%"
echo Artist=%Artist%
echo Title=%Title%
exit /B

更多详细信息,位于Split string with string as delimiter。在这样的答案上注意评论 ...

答案 1 :(得分:1)

我找不到您正在使用的所有循环for %%b in ("%%~na") do的原因,特别是因为您经常在它们的体内甚至没有使用%%b

无论如何,通过首先用文件名中禁止使用的单个字符替换子字符串(例如,:)然后使用该子字符串,可以轻松地在某个子字符串处拆分文件名。字符作为for /F循环中的定界符:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Loop through all matching files recursively:
for /R %%a in (*.mkv *.avi *.mp4) do (
    rem // Store file name in variable:
    set "NAME=%%~na"
    rem /* Toggle delayed expansion to be able to write a variable
    rem    in the same block of code without losing `!`: */
    setlocal EnableDelayedExpansion
    rem // Remove everything before first occurrence of and including ` - `:
    echo Title:  !NAME:* - =!
    rem // Replace ` - ` by `:` and use the latter as delimiter:
    for /F "tokens=1 delims=: eol=:" %%b in ("!NAME: - =:!") do (
        endlocal
        echo Artist: %%b
    )
)

endlocal
exit /B

上面的代码假定艺术家和标题部分都不为空。标题部分可以自己包含子字符串-

答案 2 :(得分:0)

这是有关如何在第一个连字符处分割文件名的示例。

@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

外部 FOR 循环在当前目录和所有子目录中递归搜索文件扩展名为mkvavimp4的未隐藏文件,并分配找到的文件的完整合格文件名(文件路径+文件名+文件扩展名),以循环变量A

内部 FOR 循环仅将文件名(不带路径和文件扩展名)解释为要处理的字符串。

将行尾字符从默认的;重新定义为默认值|,该文件名不得包含/F,以避免文件名偶然以。内部的 FOR 循环会忽略分号。

默认情况下,使用选项tokens=1* delims=- FOR 处理双引号字符串时,使用常规空格和水平制表符作为字符串定界符将字符串分成子字符串,并仅将第一个空格/制表符分隔的字符串分配给指定的循环变量。使用B修改了此字符串拆分行为,以在连字符(而不是空格/制表符)上拆分文件名字符串,方法是在文件名开头忽略连字符,并将文件名中的第一个连字符分配给指定的循环变量{ {1}}以及根据ASCII table到下一个循环变量的第一个(序列)连字符之后的所有内容,而无需进行任何进一步的字符串拆分,即循环变量C

换句话说,在像Artist - title这样的文件名上,将字符串Artist 分配给循环变量B,将字符串 title分配给循环变量C开头被分配给循环变量Title。需要删除两个不需要的空间。可以使用字符串替换来完成。但这必须使用尚未启用的delayed expansion来完成,因为包含感叹号的文件名也应正确处理。因此,接下来将在内部 FOR 循环中启用延迟的环境变量扩展。

第一个 IF 条件检查艺术家字符串的最后一个字符是否真的是空格字符,如果此条件为true,则运行字符串替换以在艺术家字符串的末尾删除该空格。

第二个 IF 条件首先检查是否也由于在文件名上执行了内部 FOR 循环的命令而完全定义了环境变量%%C完全不包含连字符,在这种情况下,Title会扩展为空字符串,因此会从环境变量列表中删除环境变量Title

嵌套的第三个 IF 条件检查所定义的环境变量Title的值的第一个字符是否为空格,并运行字符串替换以重新定义 - 而不使用第一个字符条件是真的。

现在可以输出艺术家和标题字符串,然后通过恢复以前的环境再次禁用延迟扩展。请阅读this answer,以详细了解命令 SETLOCAL ENDLOCAL ,以及每次执行 SETLOCAL ENDLOCAL时会发生什么情况,因为要做的事情不仅仅是在每个找到的文件名上启用和禁用延迟的环境变量扩展。

注意:标题部分还可以包含字符序列空格,连字符,空格以及一个或多个连字符,但是艺术家字符串当然不应包含连字符,因为会解释该字符作为艺术家和标题之间的分隔符,与连字符之间是否存在空格无关。 Windows 命令处理器不适用于像其他脚本解释器一样的增强型字符串操作。如果在艺术家和标题中分割文件名的条件必须是空格,连字符,空格而不仅仅是连字符,则必须使用不同的代码。

使用@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 将文件名分为艺术家和标题字符串的其他批处理文件代码:

call /?

但是这种仅在子例程中使用字符串替换的解决方案不适用于标题字符串,该标题字符串包含等号用作字符串替换的定界符。与上述批处理文件解决方案相比,在处理大量文件名时,它也要慢得多。

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?
  • {{1}}

另请参阅Where does GOTO :EOF return to?

答案 3 :(得分:0)

假设您的标题中始终只有一个-来自标题的分裂艺术家:

@echo off
setlocal enabledelayedexpansion

for /r %%a in (*.mkv *.avi *.mp4) do (
    set "fname=%%~na"
    set "fname=!fname: - =-!"
    for /f "tokens=1,2 delims=-" %%i in ("!fname!") do (
       echo The artist is %%i
       echo The title is %%j
       echo The extension is %%~xa
    )
)

我们将space-space替换为-,然后对其划界。