2017-08-30 63 views
1

這是我的兩個腳本的輸出。第一個調用另一個,並提供一個文件名作爲%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 

從文件名的文件名(2)它(1)移除問題的字符推斷視頻nameyear,其他變量,則(3)不一個監督filebot重命名。 setlocalendlocal位看起來不錯。它可能是從另一個腳本繼承的問題嗎?

+0

如果在delayedexpansion關閉時使用'^!'怎麼樣? – SteveFest

+0

你可以在使用delayedexpansion時使用'^!',或者在使用'enable delayedexpansion'時只使用'^^!',除非!是在引號內,那麼你仍然只需要使用'^!' –

+0

當這個'^!'在未知的文件名中時它將如何提供幫助?似乎修復問題比通過中間變量 – bricktop

回答

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 /?約上%~xI(文件的文件擴展名)延遲擴展和用於for /?幫助的更多信息執行命令以及if /?對命令幫助IFcall /?%~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條件檢查分配給環境變量字符串包含不區分大小寫:=之間指定的字符串。

即類似於使用在Ç

#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是大小寫敏感的。

+0

黑客更好,實際上.tmp是全文件名的一部分,不僅是擴展名。這是爲了防止處理臨時YTD文件。它在下載時使用'.tmp'擴展名,然後將它們組合成'* .tmp.mp4'。添加了namer.cmd。 – bricktop

+0

是否有任何方法來檢查延遲擴展是否啓用? – bricktop

+1

@bricktop是的,例如用「if」!「 ==「」echo延遲擴展已啓用.'如果啓用延遲擴展,__IF__條件僅適用,否則兩個比較的字符串永遠不會相等。 – Mofi

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! 
+1

這將很好地解釋'setlocal disabledelayedexpansion'和'setlocal enabledelayedexpansion'這兩行的確切發生,因爲除了禁用/啓用延遲擴展,可能導致堆棧溢出或其他意外行爲(取決於休息)的批次代碼。請參閱[本答案](https://stackoverflow.com/a/38676582/3074564)的下半部分,瞭解'setlocal'和'endlocal'命令的作用。 – Mofi

+0

當這對我不起作用時,會導致我遇到問題。我在啓用擴展中調用了名字腳本。但是我仍然遇到我的腳本有問題,我會繼續調試它們。 – bricktop