Welcome guest. Before posting on our computer help forum, you must register. Click here it's easy and free.

Author Topic: Advance For Loop  (Read 5952 times)

0 Members and 1 Guest are viewing this topic.

sromine

  • Guest
Advance For Loop
« on: November 30, 2006, 12:02:20 PM »
I am working on a script to copy files to remote systems.  I am stuck where I check a text file to see if this system has had the folder copied or not.  If it has, then I need to skip the IF statements and just advance the loop to check for the next system....I have put in italics the portion I am having problems with...

@echo off
for /f "tokens=*" %%i in (\\dclib3\tech\maintscript\copyscript\systems.txt) do (
        
      
      FINDSTR /C:%%i \\dclib3\tech\maintscript\copyscript\log\copyscript.txt
                IF %errorlevel%==0 then advance the loop to check for new system      
      echo %%i>>\\dclib3\tech\maintscript\copyscript\log\copyscript.txt

      IF EXIST \\%%i\C$\windows\nul (
      echo d|xcopy \\dclib3\tech\maintscript\MaintXP \\%%i\C$\ /Y /S /E
                echo Y|CACLS "\\%%i\C$\maintscript" /P everyone:F )

      IF EXIST \\%%i\C$\winnt\nul (
      echo d|xcopy \\dclib3\tech\maintscript\MaintXP \\%%i\C$\ /Y /S /E
      echo Y|CACLS "\\%%i\C$\maintscript" /P everyone:F )
                  
      )


Sidewinder



    Guru

    Thanked: 139
  • Experience: Familiar
  • OS: Windows 10
Re: Advance For Loop
« Reply #1 on: November 30, 2006, 02:09:51 PM »
Errorlevel cannot be checked as a numeric and the implied comparison is equal or greater than.

Code: [Select]
@echo off
for /f "tokens=*" %%i in (\\dclib3\tech\maintscript\copyscript\systems.txt) do (
     FINDSTR /C:%%i \\dclib3\tech\maintscript\copyscript\log\copyscript.txt
     IF errorlevel 1 (      
        echo %%i>>\\dclib3\tech\maintscript\copyscript\log\copyscript.txt
 
        IF EXIST \\%%i\C$\windows\nul (
          echo d|xcopy \\dclib3\tech\maintscript\MaintXP \\%%i\C$\ /Y /S /E
          echo Y|CACLS "\\%%i\C$\maintscript" /P everyone:F )
 
        IF EXIST \\%%i\C$\winnt\nul (
          echo d|xcopy \\dclib3\tech\maintscript\MaintXP \\%%i\C$\ /Y /S /E
          echo Y|CACLS "\\%%i\C$\maintscript" /P everyone:F )
        )        
     )

The theory here is that if errorlevel is 1 or greater (not found from the FINDSTR) then all your logic gets executed. If errorlevel is zero (found in the FINDSTR) then all your logic is skipped and the loop gets executed again with a new variable value. I tested this for syntax; I'll leave it to you for the logic portion. :D


PS. Generally I don't encourage the use of administrative shares (C$) due to  potential security issues. But hey, that's just me.
« Last Edit: November 30, 2006, 02:15:56 PM by Sidewinder »
The true sign of intelligence is not knowledge but imagination.

-- Albert Einstein

ProgressDBA



    Greenhorn

    Re: Advance For Loop
    « Reply #2 on: March 27, 2008, 01:45:51 PM »
    What about more complex logic?

    Assume that MyFile.txt is a list formatted as follows:
    SourceDrive:\SourcePath SourceFileName TargetDrive:\TargetPath


    Example:
    C:\Temp File1.txt C:\Target1
    C:\Foo File2.txt C:\Target2
    etc.


    Let's say I want to validate each element, and skip to the next iteration of the loop if any of that validation fails.

    Code: [Select]
    @ECHO OFF
    FOR /F "tokens=1-3" %%a IN (MyFile.txt) DO (

        SET SourceDir=%%a
        SET SourceFile=%%b
        SET TargetDir=%%c

    :ValidateSourceDir
        IF NOT EXIST !SourceDir! (
            ECHO Invalid Source Directory !SourceDir!
            REM Loop to the next iteration
        ) ELSE (
          ECHO Source Directory !SourceDir! Validated
        )

    :ValidateSourceFile
        IF NOT EXIST !SourceDir!\!SourceFile! (
            ECHO Invalid Source File !SourceDir!\!SourceFile!
            REM Loop to the next iteration
        ) ELSE (
          ECHO Source File !SourceDir!\!SourceFile! Validated
        )

    :ValidateTargetDir
        IF NOT EXIST !TargetDir! (
            ECHO Invalid Target Directory !TargetDir!
            REM Loop to the next iteration
        ) ELSE (
          ECHO Target Directory !TargetDir! Validated
        )

    :NowDoSomeOtherStuff
        XCOPY !SourceDir!\!SourceFile! !TargetDir!

    )

    The :Labels are there simply for readability.  Constructing this with nested, all-or-nothing execution is ugly, and a pain, especially as additional logic is needed.

    The following looks like it should do the trick, but it fails with, "The syntax of the command is incorrect.":

    Code: [Select]
    @ECHO OFF
    FOR /F "tokens=1-3" %%a IN (MyFile.txt) DO (

        SET SourceDir=%%a
        SET SourceFile=%%b
        SET TargetDir=%%c

    :ValidateSourceDir
        IF NOT EXIST !SourceDir! (
            ECHO Invalid Source Directory !SourceDir!
            REM Loop to the next iteration
            GOTO NextLoop

        ) ELSE (
          ECHO Source Directory !SourceDir! Validated
        )

    :ValidateSourceFile
        IF NOT EXIST !SourceDir!\!SourceFile! (
            ECHO Invalid Source File !SourceDir!\!SourceFile!
            REM Loop to the next iteration
            GOTO NextLoop
        ) ELSE (
          ECHO Source File !SourceDir!\!SourceFile! Validated
        )

    :ValidateTargetDir
        IF NOT EXIST !TargetDir! (
            ECHO Invalid Target Directory !TargetDir!
            REM Loop to the next iteration
            GOTO NextLoop
        ) ELSE (
          ECHO Target Directory !TargetDir! Validated
        )

    :NowDoSomeOtherStuff
        XCOPY !SourceDir!\!SourceFile! !TargetDir!

    :NextLoop

    )

    I do not get the "incorrect syntax" error if I add some place-holder statement after the :NextLoop tag, like this...
    Code: [Select]
    :NextLoop
    ECHO. > NUL

    ...BUT, if any iteration fails -- for example, with "Invalid Source File C:\Temp\NoSuchFile.txt," the loop terminates.

    How can I loop to the next iteration of a FOR loop?

    btw, I have been a fan of this site for a long time, and this is my first post!  Sorry about resurrecting an old post, but that serves two purposes: It shows that I've searched for a solution first, and it best illustrates the problem.  Thank you for your (past and future) assistance!  I hope I can contribute.

    EDIT: I know, I can validate path and file name in one step, with "IF EXIST !SourceDir!\!SourceFile!," but I wanted to illustrate a multi-stage validation process.
    « Last Edit: March 27, 2008, 01:56:26 PM by ProgressDBA »
    # find /computerhope.com/forum/posts -name "ProgressDBA" -exec rm "{}" ;

    Sidewinder



      Guru

      Thanked: 139
    • Experience: Familiar
    • OS: Windows 10
    Re: Advance For Loop
    « Reply #3 on: March 28, 2008, 06:08:26 AM »
    I suspect that the goto instructions are preempting the return address of the for loop. By fixing the syntax error, I created my own until I moved the :NextLoop outside the for loop which of course changed the entire logic of your file.

    Going back to my KISS roots, I give you this for your consideration:

    Code: [Select]
    @ECHO OFF
    FOR /F "tokens=1-3" %%a IN (MyFile.txt) DO (
    SET SourceDir=%%a
        SET SourceFile=%%b
        SET TargetDir=%%c
        set valid=Y

    :ValidateSourceDir
        IF NOT EXIST !SourceDir! (
            ECHO Invalid Source Directory !SourceDir!
            set valid=N
    )
    :ValidateSourceFile   
        IF NOT EXIST !SourceDir!\!SourceFile! (
            ECHO Invalid Source File !SourceDir!\!SourceFile!
            set valid=N
    )
    :ValidateTargetDir
        IF NOT EXIST !TargetDir! (
            ECHO Invalid Target Directory !TargetDir!
            set valid=N
        )
       
    if valid==Y XCOPY !SourceDir!\!SourceFile! !TargetDir!
    )   

    Your processor is probably fast enough not to notice the extra microseconds needed to process all the conditions before deciding to run XCOPY


     8)
    The true sign of intelligence is not knowledge but imagination.

    -- Albert Einstein

    ProgressDBA



      Greenhorn

      Re: Advance For Loop
      « Reply #4 on: March 28, 2008, 11:40:42 AM »
      KISS indeed.  Much appreciated!
      # find /computerhope.com/forum/posts -name "ProgressDBA" -exec rm "{}" ;