这是我的两个脚本的输出。第一个调用另一个并传递文件名为%1
D:\VIDEOS\SHORTS>for %v in (*) do call namer "%v"
D:\VIDEOS\SHORTS>call namer "10 Products You’ll Never Buy Again Knowing How They Are Made!.mp4"
D:\VIDEOS\SHORTS>echo "10 Products You’ll Never Buy Again Knowing How They Are Made.mp4" | find /i ".tmp" 1>nul && exit /b
echo
使用"%~nx1"
。
我的问题是:为什么感叹号会消失?
这种情况昨天开始发生,但我不确定我能做些什么才能做到这一点。它是大规模批处理脚本群集的一部分,由于大小限制,我无法在此发布所有内容,因此请求了解更多详细信息或进行概括。
编辑:请求的文件namer.cmd
set "full=" & set "file=" & set "name=" & set "type=" & set "year=" & set "episode=" & set "strict=" & set "loose="
echo "%~nx1" | find /i ".tmp" >nul && exit /b
set "file=%~n1"
:: =============================================================================================================================
:: 1. file VALIDATOR
:: =============================================================================================================================
set "original=%file%"
set "file=%file:!=%"
set "file=%file:#=%"
set "file=%file: _ = - %"
set "file=%file:’='%"
set "file=%file:“='%"
set "file=%file:”='%"
set "file=%file:[=(%"
set "file=%file:]=)%"
set "file=%file:_= %"
set "file=%file:—=-%"
set "file=%file: = %"
set "file=%file: = %"
set "file=%file:&=and%"
:: exclamation point has to be removed before we enable delayed expansion
if not "%file%"=="%original%" ren "%~1" "%file%%~x1" 2>nul && echo validated "%file%%~x1"
if not "%file%"=="%original%" if exist "%original%" ren "%~1" "%file% - copy%~x1" && echo validated "%file% - copy%~x1"
if not "%file%"=="%original%" if exist "%original%" ren "%~1" "%file% - copy 2%~x1" && echo validated "%file% - copy 2%~x1"
setlocal enabledelayedexpansion
set "original=!file!"
set "file=!file:%%=_percent!"
if not "%file%"=="%original%" ren "%~dp1%original%%~x1" "for /f "delims=" %%v in ('where /r "d:\videos" "%strict%*" 2^>nul') do" && echo validated "%original%"
set "original=!file!"
:: this needs to separated in order to add s01 tag if no season tag present
for /l %%s in (0,1,9) do set "file=!file:series.%%s.=S0%%s!"
for /l %%e in (0,1,9) do set "file=!file:%%eof2=E0%%e!"
for /l %%e in (0,1,9) do set "file=!file:%%eof3=E0%%e!"
for /l %%e in (0,1,9) do set "file=!file:%%eof4=E0%%e!"
for /l %%e in (0,1,9) do set "file=!file:%%eof5=E0%%e!"
for /l %%e in (0,1,9) do set "file=!file:%%eof6=E0%%e!"
for /l %%e in (0,1,9) do set "file=!file:%%eof7=E0%%e!"
for /l %%e in (0,1,9) do set "file=!file:%%eof8=E0%%e!"
for /l %%e in (0,1,9) do set "file=!file:%%eof9=E0%%e!"
:: if file has changed but no season tag present add s01
if not "%file%"=="%original%" echo "%file%" | find /i "s0" >nul || set "file=!file:E0=S01E0!"
if not "%file%"=="%original%" ren "%~dp1%original%%~x1" "%file%%~x1" && echo validated "%original%"
:: =============================================================================================================================
:: 2. EXTRAPOLATOR
:: =============================================================================================================================
:extrapolate
set "type=" & set "year=" & set "ss=" & set "ep=" & set "episode="
set "name=%file%"
echo "%name%"| find " " >nul || set "name=%name:.= %" & rem if no spaces then then safer to replace dots
:: if short do complete skip of movie/series extrapolator breakdown
echo "%~n1" | find /i "trailer" >nul && set "type=misc" && goto skipyear
echo "%~p1" | find /i "\shorts\" >nul && set "type=misc" && goto skipyear
echo "%~p1" | find /i "\movies\" >nul && set "type=film" && goto skipss
echo "%~p1" | find /i "\series\" >nul && set "type=show"
:: episode number: last tag first
FOR /L %%e IN (100,1,199) DO (
SET "modname=!name:E%%e=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:E%%e=& set ep=E%%e& set type=show& rem !"
GOTO gotep
)
)
FOR /L %%e IN (10,1,99) DO (
SET "modname=!name:E%%e=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:E%%e=& set ep=E%%e& set type=show& rem !"
GOTO gotep
)
SET "modname=!name:E0%%e=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:E0%%e=& set ep=E0%%e& set type=show& rem !"
GOTO gotep
)
)
FOR /L %%e IN (0,1,9) DO (
SET "modname=!name:E0%%e=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:E0%%e=& set ep=E0%%e& set type=show& rem !"
GOTO gotep
)
SET "modname=!name:E00%%e=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:E00%%e=& set ep=E00%%e& set type=show& rem !"
GOTO gotep
)
SET "modname=!name:%%eof=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:%%eof=& set ep=E0%%e& set type=show& rem !"
GOTO gotep
)
SET "modname=!name:x0%%e=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:x0%%e=& set ep=E0%%e& set type=show& rem !"
GOTO gotep
)
)
GOTO skipep
:gotep
%setcmd%
:skipep
:: season number: second to last tag second
FOR /L %%e IN (0,1,9) DO (
SET "modname=!name:S0%%e=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:S0%%e=& set ss=S0%%e& set type=show& rem !"
GOTO gotss
)
)
FOR /L %%e IN (10,1,99) DO (
SET "modname=!name:S%%e=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:S%%e=& set ss=S%%e& set type=show& rem !"
GOTO gotss
)
)
FOR /L %%e IN (0,1,9) DO (
SET "modname=!name:series.%%e=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:series.%%e=& set ss=S0%%e& set type=show& rem !"
GOTO gotss
)
)
GOTO skipss
:gotss
%setcmd%
:skipss
if defined ep if not defined ss set ss=S01
set "episode=%ss%%ep%"
:: year number: first tag last (first with brackets so not to confuse with imdb tag)
FOR /L %%e IN (1960,1,2020) DO (
SET "modname=!name:(%%e)=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:(%%e)=& set year=%%e& if not defined type set type=film& rem !"
GOTO gotyear
)
)
FOR /L %%e IN (1960,1,2020) DO (
SET "modname=!name:%%e=!"
IF "!modname!" neq "%name%" (
SET "setcmd=set name=!name:%%e=& set year=%%e& if not defined type set type=film& rem !"
GOTO gotyear
)
)
GOTO skipyear
:gotyear
%setcmd%
:skipyear
if not defined type set type=misc
:: other trimming for misc etc
set name=%name: - copy=&rem %
set name=%name: (1)=&rem %
set name=%name: (2)=&rem %
set name=%name: (3)=&rem %
set name=%name: [1]=&rem %
set name=%name: [2]=&rem %
set name=%name:360p=&rem %
set name=%name:480p=&rem %
set name=%name:720p=&rem %
set name=%name:1080p=&rem %
set name=%name:2160p=&rem %
:: changes for general use
set "name=%name: - = %"
set "name=%name: = %"
:: trim last useless letter from name
set "name=%name%endtrimmer"
set "name=%name:(endtrimmer=endtrimmer%"
set "name=%name:[endtrimmer=endtrimmer%"
set "name=%name:.endtrimmer=endtrimmer%"
set "name=%name:-endtrimmer=endtrimmer%"
set "name=%name: endtrimmer=endtrimmer%"
set "name=%name: endtrimmer=%"
set "name=%name:_endtrimmer=%"
set "name=%name:endtrimmer=%"
:: set strings
if "%type%"=="misc" set "strict=%name: =?%"
if "%type%"=="film" if defined year set "strict=%name: =?%?(%year%)"
:: caution: this allows movie to be renamed without year tag
:: if "%type%"=="film" if not defined year set "strict=%name: =?%"
if "%type%"=="show" if defined year set "strict=%name: =?%?(%year%)?%episode%"
if "%type%"=="show" if not defined year set "strict=%name: =?%?%episode%"
if "%type%"=="show" if defined year set "loose=%name: =?%?(%year%)?s"
if "%type%"=="show" if not defined year set "loose=%name: =?%?s"
FOR %%a IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET "name=!name:%%a=%%a!"
endlocal & set "full=%~dp1%file%%~x1" & set "file=%file%%~x1" & set "name=%name%" & set "type=%type%" & set "year=%year%" & set "episode=%ss%%ep%" & set "strict=%strict%" & set "loose=%loose%"
:: declare (disable never delete)
echo extrapolated %type% "%strict:?= %"
:: =============================================================================================================================
:: 3. FILEBOT MODERATOR
:: =============================================================================================================================
:: if rename not needed exit
if "%type%"=="misc" exit /b
if "%~2"=="-norename" exit /b
:: if already renamed we are done here
echo "%file%" | find /i " tt" >nul && exit /b
:: prep fake temp file
set tempdir=%temp%\%date:~3,2%%date:~6,2%%date:~11,2%%time:~1,1%%time:~3,2%%time:~6,2%%time:~9,2%
mkdir "%tempdir%" && copy /y nul "%tempdir%\%file%" >nul
:: variables (to shorten lines)
if "%type%"=="film" set cf=--db TheMovieDb --format "{n} ({y}) {director} {genres} r{rating} {vf} {vc} {ac} {imdbid}"
if "%type%"=="show" set cf=--db TheTVDb --format "{n} {s00e00} {t} {vf} {vc} {ac}-mallSanta"
:: rename fake temp file
filebot -rename "%tempdir%\%file%" --q "%name% %year%" %cf% >nul 2>nul
:: new name into variable
for /r "%tempdir%" %%i in (*) do set "new=%%~nxi"
:: declare failure
if "%file%"=="%new%" echo failed, reason: && filebot -rename "%tempdir%\%file%" --log warning --q "%name% %year%" %cf% & exit /b
:: check all strings against renamed orphan fake file and if successful rename 4real
for /f "delims=" %%v in ('where "%tempdir%:%strict%*" 2^>nul') do goto 4real
for /f "delims=" %%v in ('where "%tempdir%:%strict:s?='s?%*" 2^>nul') do goto 4real
for /f "delims=" %%v in ('where "%tempdir%:%strict:?-?=?%*" 2^>nul') do goto 4real
:: declare failure and confirm override
echo.
echo file "%file%" was renamed
echo to a "%new%", which was unexpected,
:: try the interactive command prompt mode in filebot?
choice /t 20 /c yn /n /d n /m "override and approve this rename? [Y]es or [N]o: "
if "%errorlevel%"=="1" goto 4real
exit /b
:4real
filebot -rename "%~dp1%file%" --q "%name% %year%" %cf% >nul 2>nul
if not exist "%~dp1%file%" echo successfully renamed "%file%"
:: validate the new file (maybe just send to validate with a -norename? takes longer but clearer code
set "original=%file%"
set "file=%file:!=%"
set "file=%file:#=%"
set "file=%file: _ = - %"
set "file=%file:’='%"
set "file=%file:“='%"
set "file=%file:”='%"
set "file=%file:_= %"
set "file=%file:—=-%"
set "file=%file: = %"
set "file=%file: = %"
set "file=%file:&=and%"
if not "%file%"=="%original%" ren "%~1" "%file%" && echo validated "%original%"
setlocal enabledelayedexpansion
set "original=!file!"
set "file=!file:%%= percent!"
if not "%file%"=="%original%" ren "%~dp1%original%%~x1" "%file%" && echo validated "%original%"
endlocal
exit /b
它(1.)从文件名中删除有问题的字符(2.)从文件名外推视频name
,year
,其他变量,然后(3.)进行监督filebot
改名。 setlocal
和endlocal
位看起来不错。可能是问题是从另一个脚本继承的吗?
答案 0 :(得分:3)
您已在批处理脚本setlocal EnableDelayedExpansion
中的 ECHO 行之上的某处namer
启用了延迟环境变量扩展。
因此,感叹号不会被进一步解释为文字字符,但随着变量引用的开始/结束扩展延迟。
我们需要namer
批处理文件的批处理代码来帮助您解决此问题。
看起来该行用于检查文件是否包含.tmp,即文件扩展名为.tmp
,如果是这种情况,请忽略该文件。
我建议更改您的第一个批处理文件
for %%v in (*) do call namer "%%v"
到
for %%I in (*) do if /I not "%%~xI" == ".tmp" call "%~dp0namer.cmd" "%%I"
然后.tmp
批处理文件根本不处理文件扩展名为namer
的文件。
在命令提示符窗口set /?
中运行,以获取有关延迟扩展的更多信息,并for /?
获取有关%~xI
(文件的文件扩展名)的帮助以及if /?
的帮助在命令 IF 和call /?
上获取有关%~dp0
的帮助。
也可以在namer.cmd
中使用:
if /I "%~x1" == ".tmp" goto :EOF
如果第一个参数的文件扩展名为namer.cmd
(比较不区分大小写),则退出批处理文件.tmp
的处理。对于此比较,是否启用延迟扩展无关紧要。另见Where does GOTO :EOF return to?
如果.tmp
不是文件的文件扩展名,但只是文件名中的某个位置,则可以使用带字符串替换的 IF 。
批处理文件namer.cmd
的示例。
set "FileName=%~nx1"
if not "%FileName:.tmp=%" == "%FileName%" goto :EOF
第一行指定带扩展名的文件名,但没有环境变量FileName
的路径。
第二行比较区分大小写的文件名字符串,其中所有出现的.tmp
都不区分大小写,而空字符串的文件名字符串根本没有修改。如果文件名字符串确实包含.tmp
1次或更多次,则两个比较的字符串不相等,从而导致批处理文件的退出处理。
换句话说, IF 条件检查分配给环境变量的字符串是否包含:
和=
之间指定的字符串不区分大小写。
这类似于在 C 中使用
#include <string.h>
int main(int argc, char *argv[])
{
if(argc > 1)
{
/* Does first argument contain the string ".tmp"? */
if(strstr(argv[1],".tmp") != NULL) return 1;
}
return 0;
}
函数strstr区分大小写。
答案 1 :(得分:1)
这是一种可以在不使用转义字符的情况下使用delayedexpansion的方法。
@echo off
setlocal disabledelayedexpansion
set myfile="10 Products You’ll Never Buy Again Knowing How They Are Made!.mp4"
echo %DB_password%
setlocal enabledelayedexpansion
echo !myfile!