是否可以将FINDSTR与变量而不是文件一起使用?
我已经尝试对此进行研究,但我对批处理的了解还不够。
我已经使我的大部分批处理文件完美地满足了我的需要,但是我在将字符串变量的一部分提取到新变量中时遇到了问题。
例如,原始变量为S02E12 - Charge!
。我想将 02
提取到 ep_seas
,将 12
提取到 ep_num
,然后将 Charge!
提取出来> 到 ep_name
。如果这是确切的名称模式,我现在可以正常工作,但我遇到了一些采用这种模式的文件:S02E124 - Charge #2!
有没有办法可以动态获取我需要的值,而不管它们的长度如何?
我的想法是使用 FINDSTR 在 S
和 E
之间搜索,然后在 E
和空格
(或 -
),然后在 -
和末尾之间。但我不确定如何继续。
有人有我可以研究的解决方案或者有人可以提供示例吗?
setlocal DisableDelayedExpansion
set mkvmerge="C:/Program Files/MKVToolNix/mkvmerge.exe"
set "output_folder=%cd%\Muxing"
for /r %%a in (*.mkv) do (
set fi=%%a
set ep=%%~na
call :merge
)
goto :eof
:merge
set ep_name=%ep:~9%
set ep_num=%ep:~4,2%
set ep_seas=%ep:~2,1%
call %mkvmerge% -o "%output_folder%\%ep%.mkv" --track-name "0:%ep_name%" --language 0:und --default-track 0:yes --track-name "1:[JAP]" --language 1:jpn --default-track 1:yes --track-name "2:[ENG]" --language 2:eng --default-track 2:yes --forced-track 2:yes "%fi%" --track-order 0:0,0:1,0:2 --title "Fate Zero - Episode %ep_num%"
goto :eof
最佳答案
您可以使用此代码来完成您的任务:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "output_folder=%CD%\Muxing"
for /R %%I in (*.mkv) do (
set "fi=%%I"
set "ep=%%~nI"
call :merge
)
goto :EOF
:merge
for /F "tokens=1,2* delims=ES- " %%A in ("%ep%") do (
set "ep_seas=%%A"
set "ep_num=%%B"
set "ep_name=%%C"
)
"%ProgramFiles%\MKVToolNix\mkvmerge.exe" -o "%output_folder%\%ep%.mkv" --track-name "0:%ep_name%" --language 0:und --default-track 0:yes --track-name "1:[JAP]" --language 1:jpn --default-track 1:yes --track-name "2:[ENG]" --language 2:eng --default-track 2:yes --forced-track 2:yes "%fi%" --track-order 0:0,0:1,0:2 --title "Fate Zero - Episode %ep_num%"
goto :EOF
这里使用的命令FOR/F解析双引号中的字符串,即文件名。
选项 "tokens=1,2* delims=ES- "
会导致使用 4 个指定字符作为分隔符将文件名字符串 S02E12 - Charge!
和 S02E124 - Charge #2!
拆分为 3 个子字符串。
- token 1 是分配给指定循环变量
02
的两个文件名的A
。 - token 2 是
12
和124
,根据 ASCII 表(即A
)分配给B
之后的下一个循环变量的两个文件名。 - token 3 是 token 2 之后的分隔符之后的所有内容,即分配给下一个循环变量
Charge!
的两个文件的Charge #2!
和C
。
您现在知道为什么循环变量区分大小写而环境变量不区分大小写了。指定的循环变量定义下一个循环变量在使用带有多个标记/子字符串的 for /F
时具有哪些字符。
*
附加到标记数字 X 表示子字符串 X 之后的分隔符后的字符串/行的其余部分应分配给下一个循环变量,而不需要进一步拆分分隔符。因此,S02E12 -
和 S02E124 -
之后的字符串也可以包含分隔符,但仍会完全分配给循环变量 C
。
请注意,连字符和空格后以 E 或 S 开头的字符串也被解释为分隔符,因此在分配给循环变量 C
的字符串中缺失。子例程 merge
中的 FOR 循环可以替换为以下代码,以获得像 S03E48 - Extended Version.mkv
这样的文件名的工作解决方案。
for /F "tokens=1* delims=- " %%A in ("%ep%") do (
set "ep_name=%%B"
for /F "tokens=1,2 delims=ES" %%C in ("%%A") do (
set "ep_seas=%%C"
set "ep_num=%%D"
)
)
外循环将 S03E48
分配给循环变量 A
并将 Extended Version
分配给循环变量 B
。内部循环再次将 S03E48
拆分为分配给循环变量 03
的 C
和分配给循环变量 48
的 D
。
顺便说一句:Windows 上的目录分隔符是 \
,而不是 Unix/Linux/Mac 上的 /
,尽管 Windows 内核函数还支持使用 /
的文件/目录路径,并自动更正为 \
。
为了了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
-
call /?
-
echo /?
-
endlocal /?
-
for /?
-
goto /?
-
set /?
-
setlocal /?
最后一点:
可以在环境变量上使用FINDSTR,例如:
echo %ep% | findstr /R "^S[0123456789][0123456789]"
但是FINDSTR永远不会只输出匹配的字符串。它始终输出包含找到的字符串的整行。因此,FINDSTR 对于将文件名分割成单独的部分没有任何帮助。
关于string - 如何使用 FINDSTR 查找变量值中的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46553570/