简体   繁体   中英

Windows batch script: ENABLEDELAYEDEXPANSION + For Loop not working as expected

I'm not sure how to make the following code work. The loop is not returning all supposed files and %%~FI only expands at the beginning of the FOR loop. By the time the last command executes, "%%~FI" yields a literal string rather than expanding to the desired file name:

SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%I IN (*.foo *.bar) DO (
    SET OFileBase=%%~DPNI
    ECHO "%%~FI" REM Expands correctly at this point
    :WhileLoop2
    IF EXIST "!OFileBase!.baz" (
        SET /A SuffixIndex += 1
        SET OFileBase=%%~DPNI [!SuffixIndex!]
        GOTO WhileLoop2
    )
    ECHO "%%~FI" REM Expands no more, now a literal string?!
    fooparser.exe --input "%%~FI" - | bazmaker.exe - "!OFileBase!.baz"
)
ENDLOCAL

What am I doing wrong?

SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%I IN (*.foo *.bar) DO (
    SET OFileBase=%%~DPNI
    ECHO "%%~FI" REM Expands correctly at this point
    call :WhileLoop2 "%%~DPNI"
    ECHO "%%~FI" REM Expands no more, now a literal string?!
    fooparser.exe --input "%%~FI" - | bazmaker.exe - "!OFileBase!.baz"
)
ENDLOCAL
goto :eof

:WhileLoop2
IF EXIST "!OFileBase!.baz" (
 SET /A SuffixIndex += 1
 SET OFileBase=%~1 [!SuffixIndex!]
 GOTO WhileLoop2
)
goto :eof

Always difficult working with an isolated segment of a batch - especially one that's obviously been santitised further.

Your problem is attempting to use a label within a block statement (a parenthesised series of statements). Not a good idea - confuses FOR and terminates the loop.

Since you are using the metavariable %%I within the inner loop, pass it as a quoted parameter (in case %%I contains separators) to a subroutine, then access the value within the subroutine as %~1 which removes the quotes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM