2015-09-03 186 views
2

我有以下在批處理文件中的一段代碼的選項EnableDelayedExpansion上:感嘆號衝突

:: 
:: Split 
:: 
for /F "tokens=*" %%F in ('dir /s /b *.cue') do (
    pushd . 
    cd %%~dpF 
    mkdir out 
    cd out 

    :: Set input file 
    set inFile= 
    if exist "%%~dpnF.flac" (
     set inFile="%%~dpnF.flac" 
    ) else (
     if exist "%%~dpnF" (
      set inFile="%%~dpnF" 
     ) else (
      set inFile="%%~dpF*.flac" 
     ) 
    ) 

    shntool.exe split -f "%%F" -t %%t -o flac -m /-?':' !inFile! 

    echo %ERRORLEVEL% 
    if %ERRORLEVEL% GEQ 1 (
     rmdir /q out 
    ) 
    popd 
) 

的代碼示出搜索.CUE - .FLAC雙(CD撕裂)遞歸地在當前目錄中並使用shntool進行分割。當某些目錄名稱包含與EnableDelayedExpansion選項衝突的exlamation標記(!)並且exlamation標記消失於變量擴展中時會出現問題,因此在某些對上失敗。

我該如何修改此片段以便以某種方式轉義!inFile中的exlamation標記!變量爲了使它正常工作?

回答

3

您需要從%%F中取數值而不會延遲擴展。
只需在每個循環中切換延遲擴展模式。

setlocal DisableDelayedExpansion 
for /F "tokens=*" %%F in ('dir /s /b *.cue') do (
    set "directory=%%~dpF" 
    set "file=%%~dpnF" 
    setlocal EnableDelayedExpansion 
    pushd . 
    cd !directory! 
    mkdir out 
    cd out 

    :: Set input file 
    set inFile= 
    if exist "!file!.flac" (
     set inFile="!file!.flac" 
    ) else (
     if exist "!file!" (
      set inFile="!file!" 
     ) else (
      set inFile="!file!*.flac" 
     ) 
    ) 

    shntool.exe split -f "%%F" -t %%t -o flac -m /-?':' !inFile! 

    echo !ERRORLEVEL! 
    if !ERRORLEVEL! GEQ 1 (
     rmdir /q out 
    ) 
    popd 
    endlocal 
) 
2

試試這個(該工具的所有呼叫都槽子程序):

:: 
:: Split 
:: 
for /F "tokens=*" %%F in ('dir /s /b *.cue') do (
    pushd . 
    cd %%~dpF 
    mkdir out 
    cd out 

    :: Set input file 
    set inFile= 
    if exist "%%~dpnF.flac" (
     rem set inFile="%%~dpnF.flac" 
     call :shntool "%%~dpnF.flac" 
    ) else (
     if exist "%%~dpnF" (
      rem set inFile="%%~dpnF" 
      call :shntool "%%~dpnF" 
     ) else (
      rem set inFile="%%~dpF*.flac" 
      call :shntool "%%~dpF*.flac" 
     ) 
    ) 

    rem shntool.exe split -f "%%F" -t %%t -o flac -m /-?':' !inFile! 

    echo %ERRORLEVEL% 
    if %ERRORLEVEL% GEQ 1 (
     rmdir /q out 
    ) 
    popd 
) 

exit /b 0 

:shntool 

for /l %%a in (1;1;1) do (
    shntool.exe split -f "%%F" -t %%t -o flac -m /-?':' "%%~1" 
) 

exit /b %errorlevel% 

謹防包裝for循環中subroutine.It將使訪問的初始循環的令牌。

3

你可以用一些嘗試像

:: 
:: Split 
:: 
setlocal enableextensions disabledelayedexpansion 
for /r %%F in (*.cue) do (

    if exist "%%~dpnF.flac" (
     set "inFile=%%~dpnF.flac" 
    ) else if exist "%%~dpnF" (
     set "inFile=%%~dpnF" 
    ) else (
     set "inFile=%%~dpF*.flac" 
    ) 

    setlocal enabledelayedexpansion 
    for /f "delims=" %%a in ("!inFile!") do (
     endlocal 
     2>nul md "%%~dpF\out" 
     set "shnError=" 
     pushd "%%~dpF\out" && (
      shntool.exe split -f "%%~fF" -t %%t -o flac -m /-?':' "%%~a" || set "shhError=1" 
      popd 
     ) 
     if defined shnError rmdir /s /q "%%~dpF\out" 
    ) 
) 
endlocal 

與延遲擴展的基本問題是通過禁用它,然後使用

.... 
setlocal enabledelayedexpansion 
for /f "delims=" %%a in ("!inFile!") do (
    endlocal 
    .... 

此代碼處理時使延遲擴展到允許訪問​​變量,將值存儲在for可替換參數中,然後禁用延遲擴展,以便代碼的其餘部分在禁用延遲擴展的情況下執行,但仍然可以通過檢索訪問請求需要使用for可替換參數。