Processing subdirectories

Example scripts and tips (replaces Old Scripts & Tips archive)

Moderators: Dorian (MJT support), JRL, Phil Pendlebury

Post Reply
catman
Newbie
Posts: 10
Joined: Wed Oct 07, 2015 5:34 pm

Processing subdirectories

Post by catman » Thu Oct 15, 2015 6:14 pm

This sample macro processes files in a directory and all of its subdirectories using a technique suggested by Marcus in his blog.

Code: Select all

// This macro processes a specified directory and all of its subdirectories, displaying Word .htm files in Notepad
// Progress is recorded in a desktop log file

// Ctrl-z will cancel the macro
GoSub>SenseCtrlZ

// run programs maximized/ignore extraneous spaces in commands
Let>RP_WINDOWMODE=3
Let>IGNORESPACES=1

// close any residual open Notepad windows, in case of previous Ctrl-z
Label>closeloop
IfWindowOpen>Notepad*
    CloseWindow>Notepad*
    Goto>closeloop
Endif

// unconditionally delete any previous log file
Let>log_file=%DESKTOP_DIR%\macro.log
DeleteFile>log_file
GoSub>WriteLog,==> Starting %SCRIPT_FILE%
GoSub>WriteLog,==> We will skip Recycle bin files, files in the 'templates' subdirectories, and '~' files

// default to the I:\ drive, but allow browsing
Let>INPUT_BROWSE=2
Input>the_dir,Browse to the root directory to be scanned%CRLF%Press Ctrl-z to abort Macro Scheduler,i:

// you can recurse with MS commands if you wish ... https://www.mjtnet.com/forum/viewtopic.php?f=9&t=8185
// but as Marcus notes, CMD is simpler ............ https://www.mjtnet.com/blog/2009/08/25/the-power-of-dos-looping-through-subfolders/

// wait for CMD to finish before resuming macro
Let>RP_WAIT=1
// /s processes subdirectories, /b returns just the bare file full path, > pipes the command output into a file
Run>CMD /c dir /s /b %the_dir%\*.htm > %TEMP_DIR%pathdata.txt

// read the command output text file into a single string variable that looks like this: "path1CRLFpath2CRLFpath3CRLF..."
Readfile>%TEMP_DIR%pathdata.txt,pathString

// distribute the CRLF-delimited paths into array 'pathArray' as pathArray_1, pathArray_2, ...
Separate>pathString,CRLF,pathArray

// dunno why the last item is empty! ... we'll chop it off by shrinking the array by one item
Let>x=pathArray_count
Let>finalArrayItem=pathArray_%x%
Len>finalArrayItem,pathLen
If>pathLen=0
    Sub>pathArray_count,1
Endif

// exit if there are no files
If>pathArray_count=0
    MessageModal>No files found!
    Exit
Endif


// loop thru the array of file paths
// counting the files found, files skipped, and files processed (in this test macro, displayed by Notepad)
Timer>startTime
Let>found_count=0
Let>skipped_count=0
Let>processed_count=0
Let>x=0
Repeat>x
    Add>x,1
    Add>found_count,1
    Let>curr_path=pathArray_%x%
    GoSub>WriteLog,File #%x% %curr_path% found
    GoSub>SetDoitFlag
    If>doit_flag=TRUE
        GoSub>Doit
    Endif
Until>x,patharray_count
GoSub>ExitMsg
Exit>0

// *** BAILOUT (due to Ctrl-z)
SRT>Bailout
    // disable Ctrl-z processing
    OnEvent>KEY_DOWN,VK90,2,
    GoSub>WriteLog,Ctrl-z pressed ... cancelling the program
    Let>x=5
    Repeat>x
        Message>Ctrl-z pressed ... cancelling the program ... %x%
        Wait>1
        Sub>x,1
    Until>x=0
    CloseWindow>Macro Scheduler Message
    GoSub>ExitMsg
    Exit>0
END>Bailout

// *** DOIT
SRT>Doit
    Add>processed_count,1
    // run maximized 
    Let>RP_WINDOWMODE=3
    // don't wait for Notepad to finish before resuming macro
    Let>RP_WAIT=0
    Run>Notepad %curr_path%
    // close Notepad quickly
    WaitWindowOpen>Notepad*
    Wait>0.1
    CloseWindow>Notepad*
END>Doit

// *** EXITMSG
SRT>ExitMsg
    // write a detailed message to the log file, reporting processing information counts
    // trailing blanks are ignored in commands, so we'll include the system space variable
    Timer>endTime
    Let>elapsed_minutes={round((%endTime%-%startTime%)/1000/60)}
    Let>screenMsg=%pathArray_count% file(s) found in directory ...%SPACE%%CRLF%
    ConCat>screenMsg,%skipped_count% file(s) skipped ...%SPACE%%CRLF%
    ConCat>screenMsg,%processed_count% file(s) processed ...%SPACE%%CRLF%
    ConCat>screenMsg,%elapsed_minutes% minute(s) elapsed
    StringReplace>screenMsg,CRLF,SPACE,logMsg
    GoSub>WriteLog,logMsg
    MessageModal>(Press OK to view the log file)%CRLF%%screenMsg%
    Run>notepad.exe %log_file%
END>ExitMsg

// *** SENSECTRLZ
SRT>SenseCtrlZ
    Let>x=5
    Repeat>x
        Message>Press Ctrl-Z at any time to cancel ... %x%
        Wait>1
        Sub>x,1
    Until>x=0
    CloseWindow>Macro Scheduler Message
    // if Ctrl-z is pressed, perform the Bailout subroutine
    OnEvent>KEY_DOWN,VK90,2,Bailout
END>SenseCtrlZ

// *** SETDOITFLAG
SRT>SetDoitFlag
    // skip certain files that we don't want to process
    Let>doit_flag=TRUE
    Position>$RECYCLE.BIN,curr_path,1,recyclePos
    If>recyclePos>0
        GoSub>WriteLog,File #%x% %curr_path% recycle bin file skipped
        Goto>skipit
    Endif
    Position>templates,curr_path,1,templatesPos
    If>templatesPos>0
        GoSub>WriteLog,File #%x% %curr_path% template file skipped
        Goto>skipit
    Endif
    Position>~,curr_path,1,squigglePos
    If>squigglePos>0
        GoSub>WriteLog,File #%x% %curr_path% squiggle file skipped
        Goto>skipit
    Endif
    // fall through here without skipping any files
    Goto>letsdoit
    // come here to skip the file
    Label>skipit
      Let>doit_flag=FALSE
      Add>skipped_count,1
    // come here in order NOT to skip the file
    Label>letsdoit
END>SetDoitFlag

// *** WRITELOG 
SRT>WriteLog
    Let>log_msg=%WriteLog_var_1%
    DateStamp>log_file,%SCRIPT_NAME% %log_msg%
END>WriteLog

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts