我一直在编写一个批处理脚本来对我存储在电脑上的约 7tb 的翻录媒体进行编目。虽然大部分脚本都有效,但我一直停留在自动确定文件夹是否包含电视节目或电影的部分。该函数的工作原理是通过获取根文件夹的名称(例如 Die_Hard)为每个类别(电影与电视)分配一个权重值,处理可能存在于其中的任何子文件夹的名称,并吐出一个值,然后主程序将其转换电视为 T,电影为 M,以及置信度分数。我遇到的问题是该函数无法正确解析关键字,并将电视节目标记为电影,反之亦然。如果我手动进行计算,效果很好,但我通常为 Bash 编写脚本,而且我不太明白这里不起作用。
:DETERMINE
setlocal EnableDelayedExpansion
REM DT NAME
set "DTNM=%~1"
echo %DTNM%
REM DT Location
set "DLOC=%~2"
REM echo %DLOC%
REM DT Score
set /A dtq=0
REM DT Movie Weight
set /A DTMV=0
REM DT TV Weight
set /A DTTV=0
REM DT TV Keywords
set "DTTR=Season,90;Volume,70;TV,45;S1,100;V1,75;"
REM DT Movie Keywords
set "DMVT=%DTNM%,45;Theatrical,90;Extended,60;Unrated,60;Extra,5;Bonus,10;Bonus-Content,15;Bonus-Disc,12;Bonus-Disk,12;Bonus_Content,15;Bonus_Disc,12;Bonus_Disk,12;Bonus Content,15;Bonus Disc,12;Bonus Disk,12;Special,2;Special-Features,18;Special-Content,15;Special_Features,18;Special_Content,15;Special Features,18;Special Content,15;"
REM DMTV Calculator
REM Iterate through subfolders
for /f "tokens=*" %%U in ('dir /b /ad "%DLOC%"') do (
REM Iterate through Keyword list
for /f "tokens=* delims=;" %%V in ("%DMVT%") do (
REM Split Keyword from weight
REM echo %%V
for /f "tokens=1-2 delims=," %%W in ("%%V") do (
echo %%U|find /I "%%X" >nul
if errorlevel 0 ( @set /A DMTV=!DMTV! + %%X )
REM echo %%U %%W %%X
echo 1
)
)
REM DMTV escapw workaround
set DMTV=!DMTV!
)
REM DTTV Calculator
REM Iterate through subfolders
for /f "tokens=*" %%T in ('dir /b /ad "%DLOC%"') do (
REM Iterate through keyword list
for /f "tokens=* delims=;" %%S in ("%DTTR%") do (
REM split keyword from weight
for /f "tokens=1-2 delims=," %%Q in ("%%S") do (
echo %%T|find /I "%%R" >nul
REM echo %%T %%Q %%R
if errorlevel 0 ( @set /A DTTV=!DTTV! + %%R )
)
)
REM DMTV escapw workaround
set DTTV=!DTTV!
)
echo %DMTV% %DTTV%
set /A DEQ=%DMTV% - %DTTV%
echo %DEQ%
ENDLOCAL
GOTO:EOF
仅供参考,电视节目的子文件夹是季/卷号(例如 S1、S2),而电影则直接位于根文件夹下,但系列和三部曲除外,其子文件夹与根文件夹,但也有指示电影的数字。
脚本应该为电影输出正数,为电视节目输出负数。数字离 0 越远,置信度分数就越高。我有一个脚本版本,它使用 20 多个嵌套的 If 语句,但无法添加新关键字,有时会输出不正确的数字。我尝试以不同的方式解析关键字,甚至使用两个字符串,一个用于关键字,一个用于随附的评级。如果这是 bash,我可以使用数组,但据我所知,这是不可能的。
该函数的输出应如下所示:
45
(对于电影或系列电影)或 -100
对于电视节目。
主程序解析输出后,它看起来像这样:
Discs
Airplane - 2 Movies - 100% (90) [1080/XX GB]
...
JOHN WICK - 4 Movies - 100% (180) [UHD/XX GB]
...
The Office - 9 Seasons - 100% (-900) [NTSC/XX GB]
...
但是目前,子程序的输出如下所示:
外壳窗口:
...
Airplane
Missing operator.
1
Missing operator.
1
Missing operator.
Missing operator.
90 180
-90
...
主程序输出:
Airplane - 90 Seasons - 90% (-90) [1080/XX GB]
我暂时休息了一下……但我想通了。 现在它会输出每个类别的正确权重。
setlocal EnableDelayedExpansion
REM DT NAME
set "DTNM=%~1"
REM DT Location
set "DLOC=%~2"
set DDBG=0
if %DDBG% EQU 1 ( echo # ---%DTNM% & echo # %DLOC%)
REM DT Score
set /A dtq=0
REM DT Movie Weight
set /A DTMV=10
REM DT TV Weight
set /A DTTV=0
REM DT TV Keywords
set "DTTR=Season,90;Volume,70;TV,45;^S[0123456789][0123456789],100;^S[0123456789],100;^V[0123456789][0123456789],75;"
REM DT Movie Keywords
set "DMVT=%DTNM%,45;^[0123456789],10;Theatrical,90;Extended,60;Unrated,60;Extra,5;Bonus,10;Bonus-Content,15;Bonus-Disc,12;Bonus-Disk,12;Bonus_Content,15;Bonus_Disc,12;Bonus_Disk,12;Bonus Content,15;Bonus Disc,12;Bonus Disk,12;Special,2;Special-Features,18;Special-Content,15;Special_Features,18;Special_Content,15;Special Features,18;Special Content,15;"
set DMTC=0
set DMMC=0
REM DMTV Calculator
REM Iterate through subfolders
for /f "tokens=* delims=" %%U in ('dir /b /ad "%DLOC%"') do (
REM Iterate through Keyword list
for %%V in ("%DMVT:;=" "%") do (
REM Split Keyword from weight
REM echo %%V
for /f "tokens=1-2 delims=," %%W in (%%V) do (
REM echo %%U
REM echo | set /p= is equivalent to echo -n
if %DDBG% EQU 1 (echo | set /p=# "TITLE" %%U "TOKEN" %%W "WEIGHT" %%X)
echo %%U|findstr /R /I /M "%%W" >nul
if !errorlevel!==0 ( @set /A DMTV=!DMTV! + %%X & if %DDBG% EQU 1 (echo "Match")) else (if %DDBG% EQU 1 (echo "No Match"))
REM echo %%U %%W %%X
REM echo 1
set /A DMMC+=1
)
)
REM DMTV escapw workaround
set DMTV=!DMTV!
)
REM DTTV Calculator
REM Iterate through subfolders
for /f "tokens=*" %%U in ('dir /b /ad "%DLOC%"') do (
REM Iterate through keyword list
for %%V in ("%DTTR:;=" "%") do (
REM split keyword from weight
for /f "tokens=1-2 delims=," %%W in (%%V) do (
REM echo | set /p= is equivalent to echo -n
if %DDBG% EQU 1 (echo | set /p=# "TITLE" %%U "TOKEN" %%W "WEIGHT" %%X)
echo %%U|findstr /R /I /M "%%W" >nul
REM echo %%T %%Q %%R
if !errorlevel!==0 ( @set /A DTTV=!DTTV! + %%X & if %DDBG% EQU 1 (echo "Match")) else (if %DDBG% EQU 1 (echo "No Match"))
set /A DMTC+=1
)
)
REM DMTV escapw workaround
set DTTV=!DTTV!
)
REM empty movie score workaround (adds one to movie in case score is null or 0)
set /A DMTV+=1
if %DDBG% EQU 1 (echo # "MOV ITR" !DMMC! "TV ITR" !DMTC! "MOV SCR" %DMTV% "TV SCR" -%DTTV%)
set /A DEQ=%DMTV% - %DTTV%
if %DDBG% EQU 1 (echo %DEQ%)
set U=
ENDLOCAL & set "DEQ=%DEQ%"
GOTO:EOF
以下是我修复的内容的摘要:
Find
替换了FindStr
。通过使用 FindStr
我获得了使用正则表达式的能力。这允许检测文件夹名称中的数字。FindStr
输出 3 个错误条件。 0
表示成功,1
表示不匹配,2
表示失败。这意味着 if errorlevel 0
是这种情况下的正确用法。此外,当启用 if errorlevel 0
时,if !errorlevel!==0
相当于 DelayedExpansion
。for
语句生成大量令牌时,使用不同的变量实际上会导致更多问题。for
的情况下,我必须使用标准的 for %%V in ("%DTTR:;=" "%")
循环,因为它是 not 循环遍历目录,并且我不希望每个令牌都获得自己的变量。我需要它一次解析一个标记并且只使用一个变量,在这种情况下%%V
。%%X
中使用 %%W
而不是 FindStr
。这意味着它正在搜索权重而不是关键字。DMTV
(电影计算的最终值)加1,因为当指定目录中没有文件夹时DMTV
被清除。