0

I'm doing a job, copying files from one location to another location using BATCH file. I split my statements into three parts, one program driver, one for generating file list under each sub-directory, and one for checking file name & doing actual copy stuff.

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 STUFF

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

My question is, why my "ENDLOCAL & SET" statement not working, i.e., NULL each time, as pictures show. How can I change my statements to make it work as expected?

First image

Second image


I changed part 3 to

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
    )
)

It seems that RES always defined, even FILENAME is in specified ranges. In this case, it copied wrong files.

New runtime result

6
  • Please don't link to external sites - there is too high a probability that the link will become invalid. There's a magic 'graphic' button available over the edit box to include graphics by uploading them to SO. Commented Jan 24, 2015 at 7:28
  • when I post this thread, SO notices me that I need at least 10 reputation to upload images. So I take an intermediate way. Thanks, Magoo Commented Jan 24, 2015 at 7:41
  • Yeah -puts the brakes on spammers. Pain for legitimate users. I've no objection to blue-pencilling legitimate posts thogh. HTH. Commented Jan 24, 2015 at 7:53
  • Hi Magoo, it's inconvenient to place code in comments. I posted another answer. Please help to improve. Thanks, bro Commented Jan 24, 2015 at 9:14
  • I've reduced the title volume too. Caps are discouraged. And added the cmd tag as NIXers use batchfiles too. BTW: You can redirect cmd output to a file by using *yourbatchname >*afilename* - that should make it easier to post runtime reports - no need for images. Commented Jan 24, 2015 at 9:48

1 Answer 1

1

in (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
    )
)

Within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed - the same thing applies to a FOR ... DO (block).

Hence, IF (something) else (somethingelse) will be executed using the values of %variables% at the time the IF is encountered.

Two common ways to overcome this are 1) to use setlocal enabledelayedexpansion and use !var! in place of %var% to access the changed value of var or 2) to call a subroutine to perform further processing using the changed values.

Note therefore the use of CALL ECHO %%var%% which displays the changed value of var. CALL ECHO %%errorlevel%% displays, but sadly then RESETS errorlevel.

Where flags are involved, the situation changes again. set "flag=" will ensure a flag is cleared. set "flag=somethingelse" will ensure it is set (the value is not relevant.) Using if defined flag (doiftrue) else (doiffalse) works on the run-time (current) status of flag - not the parse-time value.

Hence, I suggest you change your processing, setting ccc to either nothing with a set "ccc=" statement or something with a set "ccc=y" and you can then test for true/false using if [not] defined ccc

The syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned. set /a can safely be used "quoteless".


(on revised code)

Your tests are incorrect.

res will not be set to Y with value CH145... against CH201... But it will be set to Y in the LEQ test as CH145... is lestt than or equal to CH300...

You may either cascade the setting:

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

or gate the test

IF "%%C" GEQ "CH201_00000000_000.WAV" SET "RES=Y"
if defined res IF "%%C" GTR "CH300_FFFFFFFF_FFF.WAV" SET "RES=" 
Sign up to request clarification or add additional context in comments.

1 Comment

IN my origrinal code, I used cascaded IF for condition tests. But I changed to multiple statements for dedugging. Now it works as expected. Thanks, Magoo :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.