Endlocal & "set var" 在 "for" 循环中没有按预期工作

Endlocal & "set var" not working as expected in "for" loop

我正在做一项工作,使用 BATCH 文件将文件从一个位置复制到另一个位置。我将语句分为三个部分,一个程序 driver,一个用于在每个 sub-directory 下生成文件列表,另一个用于检查文件名和执行实际的复制操作。

1.PROGRAM DRIVER

IF EXIST TEMP.TXT DEL TEMP.TXT
CD>TEMP.TXT
set /p ROOT=<TEMP.TXT

rem PARA is the date to copy
SET PARA=2013-08-06
ECHO %PARA%
CD %ROOT%\%PARA%
FOR /R %%A IN (.) DO (    ::COPY SUB-LOGIC FILE TO EACH SUB-DIRECTORY
    ECHO NOW IN %%A
    CD %%A
    XCOPY "%ROOT%\WORK.BAT" . /K /Y
    XCOPY "%ROOT%\CORE.BAT" . /K /Y
    ECHO LOOP OUT.
)

CD %ROOT%\%PARA%
FOR /R %%A IN (.) DO (
    ECHO NOW IN %%A
    CD %%A
    CALL WORK.BAT        ::GENERATING FILE LIST
    ECHO LOOP OUT.
)

CD %ROOT%\%PARA%
FOR /R %%A IN (.) DO (
    ECHO NOW IN %%A
    CD %%A
    CALL CORE.BAT        ::DOING COPY STUFF
    ECHO LOOP OUT.
)

PAUSE

2.WORK.BAT

IF EXIST FILE.TXT DEL FILE.TXT
FOR %%B IN (*.wav) DO ECHO %%~nxB>>FILE.TXT

3.COPYING 东西

FOR %%F IN ("%CD%") DO SET CURDIR=%%~nxF
IF NOT EXIST FILE.TXT GOTO END
SET CCC="FALSE"  ::IF NO CCC DECLARED HERE,BELOW FOR LOOP WILL BE SKIPPED
PAUSE
FOR /F %%C IN (FILE.TXT) DO (
    SETLOCAL
    SET RES="FALSE"
    IF "%%C" GEQ "CH201_00000000_000.WAV" SET RES="TRUE"
    IF "%%C" LEQ "CH300_FFFFFFFF_FFF.WAV" (
         SET RES="TRUE"
    ) ELSE ( SET RES="FALSE")
    ENDLOCAL& SET CCC=%RES%    *::VAR CCC NOT UPDATED*
    PAUSE
    IF %CCC% EQU "TRUE" (
        IF NOT EXIST D:\PHILIPS\%PARA%\%PARA%\%CURDIR% MD D:\PHILIPS\%PARA%\%PARA%\%CURDIR%
        XCOPY "%ROOT%\%PARA%\%CURDIR%\%%C" D:\PHILIPS\%PARA%\%PARA%\%CURDIR% /K /Y
    )
)
:END
ECHO LOOP OUT

我的问题是,为什么我的 "ENDLOCAL & SET" 语句不起作用,即每次都是 NULL,如图所示。我怎样才能更改我的语句以使其按预期工作?


我将第 3 部分更改为

FOR %%F IN ("%CD%") DO SET CURDIR=%%~nxF
IF NOT EXIST FILE.TXT GOTO END
SET "RES="
PAUSE
FOR /F %%C IN (FILE.TXT) DO (
    SET "RES="
    IF "%%C" GEQ "CH201_00000000_000.WAV" SET "RES=Y"
    IF "%%C" LEQ "CH300_FFFFFFFF_FFF.WAV" (
        SET "RES=Y"
    ) ELSE ( SET "RES=" )
    PAUSE
    IF DEFINED RES (
            IF NOT EXIST D:\PHILIPS\%PARA%\%PARA%\%CURDIR% MD D:\PHILIPS\%PARA%\%PARA%\%CURDIR%
            XCOPY "%ROOT%\%PARA%\%CURDIR%\%%C" D:\PHILIPS\%PARA%\%PARA%\%CURDIR% /K /Y
    )
)

似乎RES总是定义的,连FILENAME都在指定的范围内。在这种情况下,它复制了错误的文件。

在 (3)

FOR /F %%C IN (FILE.TXT) DO (
    SETLOCAL
    SET RES="FALSE"
    IF "%%C" GEQ "CH201_00000000_000.WAV" SET RES="TRUE"
    IF "%%C" LEQ "CH300_FFFFFFFF_FFF.WAV" (
         SET RES="TRUE"
    ) ELSE ( SET RES="FALSE")
    ENDLOCAL& SET CCC=%RES%    *::VAR CCC NOT UPDATED*
    PAUSE
    IF %CCC% EQU "TRUE" (
        IF NOT EXIST D:\PHILIPS\%PARA%\%PARA%\%CURDIR% MD D:\PHILIPS\%PARA%\%PARA%\%CURDIR%
        XCOPY "%ROOT%\%PARA%\%CURDIR%\%%C" D:\PHILIPS\%PARA%\%PARA%\%CURDIR% /K /Y
    )
)

在块语句 (a parenthesised series of statements) 中,解析 整个 块并执行 then。块中的任何 %var% 将被该变量的值替换 在块被解析时 - 在执行块之前 - 同样的事情适用于 FOR ... DO (block).

因此,IF (something) else (somethingelse) 将在遇到 IF 时使用 %variables% 的值执行。

克服此问题的两种常见方法是 1) 使用 setlocal enabledelayedexpansion 并使用 !var! 代替 %var% 来访问 var 的更改值或 2)调用子例程以使用更改后的值执行进一步处理。

因此请注意 CALL ECHO %%var%% 的使用,它显示 var 的更改值。 CALL ECHO %%errorlevel%% 显示,但遗憾的是随后重置错误级别。

涉及旗帜的地方,情况又变了。 set "flag=" 将确保标志被清除。 set "flag=somethingelse" 将确保它已设置(该值不相关。)使用 if defined flag (doiftrue) else (doiffalse) 适用于 运行-time(当前)状态 flag - 不是 解析时间 值。

因此,我建议您更改您的处理方式,将 ccc 设置为带有 set "ccc=" 语句的 nothing 或带有 set "ccc=y" 的东西然后您可以使用 if [not] defined ccc

测试 true/false

语法 SET "var=value"(其中值可能为空)用于确保分配的值中不包含任何杂散的尾随空格。 set /a 可以放心使用 "quoteless".


(修改后的代码)

您的测试不正确。

res 设置为 Y,值 CH145... 反对 CH201... 但它 LEQ 测试中设置为 Y 因为 CH145... 小于或等于至 CH300...

您可以级联设置:

if "%%C" GEQ "CH201..." IF "%%C" LEQ "CH300..." set "res=Y"

或测试

IF "%%C" GEQ "CH201_00000000_000.WAV" SET "RES=Y"
if defined res IF "%%C" GTR "CH300_FFFFFFFF_FFF.WAV" SET "RES="