感叹号与批处理文件中的EnableDelayedExpansion冲突

时间:2015-09-03 07:09:05

标签: batch-file

我在批处理文件中有以下代码,其中包含选项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 rips),并使用shntool将它们拆分。当某些目录名称包含与EnableDelayedExpansion选项冲突的感叹号(!)并且变量扩展中的感叹号消失时,会出现问题,从而导致某些对失败。

如何修改此代码段以某种方式逃避!inFile!变量中的感叹号,以使其正常工作?

3 个答案:

答案 0 :(得分: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
    ....

此代码启用延迟扩展以允许访问inFile变量,将值存储在for可替换参数中,然后禁用延迟扩展,以便在禁用延迟扩展的情况下执行其余代码但仍然可以使用for可替换参数检索以访问所需的值。

答案 1 :(得分: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 :(得分: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%

请注意子程序中的循环包装器。它将使初始循环的标记可访问。