2

This batch is to create a report which outputs the latest file of a folder. Main purpose is to see the date of generated files inside directories. To also easily check whether the target directory is update or not.

Issue :
Change the output to get the three latest files instead, also got stuck here with the For Loop inside another For Loop, I'm also using delayed expansion.

Try to use delayed expansion variable inside FOR loop (!forOPT!)

FOR ... (
    FOR /F "!forOPT!" %%a IN ('dir "!path2check!" /A-D /OD /t:w ^| FIND "/"') DO ( )
)

I would like to use variable "forOPT" in an another For Loop as to replace the "skip=10 tokens=1-5" but since For Loop doesn't like delayed expansion (!forOPT!), I'm stuck.

Edit :

Issue is now solved by the suggestion and advice of Mofi. Thank you Mofi.

As for the answer to show how, also had been made by Jeb. So thank you too Jeb.

The solution to my regarding issue is to use a CALL function instead of nesting FOR loops.

Please see my answer for the final code with also some tweaks and additional requirement to accomplish my needs.

@if (@CodeSection == @Batch) @then
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET "path2check=NULLLL"
SET "TargetDIR=%~dp0"
SET "curPATH=%~F0"
SET "newSize1=0"
SET JScall=Cscript //nologo //E:JScript !curPATH!
FOR /f "usebackq delims=" %%I IN (destPath.txt) DO (
SET "path2check=%%I"
SET cnt=0
SET totalSkip=1
FOR %%A IN ("!path2check!\*") DO SET /a cnt+=1
SET /a totalSkip=!cnt!-3

SET "forOPT=skip=!totalSkip! tokens=1-5"

ECHO !forOPT! ^<^<^< shows option
ECHO.

ECHO ---------------------

FOR /F "!forOPT!" %%a IN ('dir "!path2check!" /A-D /OD /t:w ^| FIND "/"') DO (
    SET "Date1=%%a"
    SET "Time1=%%b"
    SET "Time2=%%c"
    SET "Size1=%%d"
    SET "Filename1=%%e"
    SET newSize1=!size1:,=!
    IF !newSize1! LEQ 1000 (
      SET "newSize2=!newSize1! Bytes"
    )
    IF !newSize1! GEQ 1000 (
      FOR /F %%a IN ('!JScall! "!newSize1!/1024"') DO SET "newSize2=%%a"
      FOR /F "delims=." %%z IN ("!newSize2!") DO SET "newSize2=%%z KB"
    )
    IF !newSize1! GEQ 1000000 (
      FOR /F %%a IN ('!JScall! "!newSize1!/1024/1024"') DO SET  "newSize2=%%a"
      FOR /F "delims=." %%z IN ("!newSize2!") DO SET "newSize2=%%z MB"
    )
    ECHO !Filename1! - !newSize2! - !Time1!!Time2! - !Date1!
    )
    ECHO - EOR - !path2check!
    ECHO.
)
GOTO :EOF

@end
WScript.ECHO(eval(WScript.Arguments.Unnamed.Item(0)));

The report should also look like below. (The three latest file of each directory)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Most recently file of path : E:\

Date: dd/mm/yyyy hh:mmPM   |   Size: xxx MB  |   Filename: abc.abc
Date: dd/mm/yyyy hh:mmPM   |   Size: xxx MB  |   Filename: abc.abc
Date: dd/mm/yyyy hh:mmPM   |   Size: xxx MB  |   Filename: abc.abc

                   -   EOR   -

This batch file was also combined and mixed together from many sites on both StackOverflow (<Thank you) and SS64 (<Thank you).

Even in explaining I'm not that good, but you can ask and I can clarify. :)

If the title need to be edited please let me know, this also may help others with similar problems.

Thank you Stack Overflow, Mofi and Jeb.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
Double Quotes
  • 125
  • 1
  • 2
  • 11
  • where `forOPT` is used? – npocmaka Nov 28 '15 at 16:58
  • 1
    I suppose you used something like `for /f "skip=!forOpT" ...`. This doesn't work as it's not possible to use delayed expansion nor FOR parameter expansion in the FOR-options – jeb Nov 28 '15 at 17:55
  • its not used yet, but also try to use it at the *For loop* where "skip=10 tokens=1-5" is. Because the skip number depends actually on the files inside the folder (-3) – Double Quotes Nov 28 '15 at 17:59
  • @jeb Yes, thats the problem. – Double Quotes Nov 28 '15 at 18:00
  • 2
    The easiest method to avoid issues like that is using command __CALL__ in outer __FOR__ loop to run a subroutine containing the inner __FOR__ loop. Run in a command prompt window `call /?` for help about subroutines. There are also thousands of examples on Stack Overflow. – Mofi Nov 28 '15 at 18:54
  • @Mofi Thank you, I'm almost done also with your suggestion ! Really appreciate this solution. Thanks Mofi ! – Double Quotes Nov 29 '15 at 08:00
  • 1
    Please do not include a solution into the question, consider to post it as an answer... – aschipfl Nov 29 '15 at 20:00
  • @aschipfl Well noted. Thanks ! – Double Quotes Nov 30 '15 at 05:10

2 Answers2

2

In the FOR options only the percent expansion works, therefore you need to use a function.

FOR /f "usebackq delims=" %%I IN (destPath.txt) DO (
  ...
  SET "forOPT=skip=!totalSkip! tokens=1-5"
  call :innerLoop
)

:innerLoop
FOR /F "%forOPT%" %%a IN ('dir "!path2check!" ...) do (
  ....
)
exit /b
jeb
  • 78,592
  • 17
  • 171
  • 225
  • Hi Jeb, Thank you for the example here, so far I tested it since yesterday with suggestion from Mofi that I should do a *CALL* instead. And yes it works out almost fine but need to rewrite my code. Once done and fully works I will also mark this as answer. Thank you Jeb !! – Double Quotes Nov 29 '15 at 07:59
0

With help and suggestion of Mofi and Jeb this is what I came up with.

  • Get target path from a text file.
  • List the latest three files from the target path.
  • Final code.

    @if (@CodeSection == @Batch) @then
    @ECHO OFF
    SETLOCAL ENABLEDELAYEDEXPANSION
    
    SET "path2check=NULLLL"
    SET "TargetDIR=%~dp0"
    SET "curPATH=%~F0"
    SET "newSize1=0"
    SET JScall=Cscript //nologo //E:JScript !curPATH!
    
    FOR /f "usebackq delims=" %%I IN (destPath.txt) DO (
      SET "path2check=%%I"
      ECHO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ECHO(
      ECHO Most recently file of path : !path2check:~0,47!
      ECHO(
      CALL :countFilesFunc path2check forOPT Date1 Time1 Time2 newSize2 Filename1
      ECHO(
      ECHO                        -   EOR   -
      ECHO(
    )
    GOTO :EOF
    
    REM- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    REM- Count files in folder function section starts below
    REM- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    :countFilesFunc    - passing a variable by reference
    SET "cnt=0"
    SET "totalSkip=1"
    FOR %%A IN ("!path2check!\*") DO SET /a cnt+=1
    SET /a totalSkip=!cnt!-3
    SET "forOPT=skip=!totalSkip! tokens=1-4*"
    
    FOR /F "%forOPT%" %%a IN ('dir "!path2check!" /A-D /OD /t:w ^| FIND "/"') DO (
      SET "Date1=%%a"
      SET "Time1=%%b"
      SET "Time2=%%c"
      SET "Size1=%%d"
      SET "Filename1=%%e"
      SET newSize1=!size1:,=!
      IF !newSize1! LEQ 1000 (
        SET "newSize2=!newSize1! Bytes"
      )
      IF !newSize1! GEQ 1000 (
        FOR /F %%a IN ('!JScall! "!newSize1!/1024"') DO SET "newSize2=%%a"
        FOR /F "delims=." %%z IN ("!newSize2!") DO SET "newSize2=%%z KB"
      )
      IF !newSize1! GEQ 1000000 (
        FOR /F %%a IN ('!JScall! "!newSize1!/1024/1024"') DO SET "newSize2=%%a"
        FOR /F "delims=." %%z IN ("!newSize2!") DO SET "newSize2=%%z MB"
      )
      ECHO !Filename1!> tempfile.txt
      FOR %%? IN (tempfile.txt) DO ( SET /A strlength=%%~z? - 2 )
      IF !strlength! GEQ 15 SET "Filename1=!Filename1:~0,15!.."
      ECHO Date: !Date1! !Time1!!Time2!   ^|   Size: !newSize2!  ^|   Filename: !Filename1!
    )
    ECHO.
    GOTO :EOF
    
    @end
    WScript.ECHO(eval(WScript.Arguments.Unnamed.Item(0)));
    
  • See below example of the output.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Most recently file of path : E:\
    
    Date: 05/07/2015 08:19PM   |   Size: 278 MB  |   Filename: 353.30-desktop-..
    Date: 09/07/2015 08:27PM   |   Size: 2 MB  |   Filename: teracopy.exe
    Date: 10/07/2015 09:23PM   |   Size: 51 Bytes  |   Filename: a amprex.txt
    
                   -   EOR   -
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Most recently file of path : C:\NVIDIA\DisplayDriver\337.88\Win8_WinVista_Wi
    
    Date: 11/06/2014 03:58PM   |   Size: 27 KB  |   Filename: setup.cfg
    Date: 11/06/2014 03:58PM   |   Size: 14 KB  |   Filename: EULA.txt
    Date: 11/06/2014 04:01PM   |   Size: 200 KB  |   Filename: ListDevices.txt..
    
                   -   EOR   -
    
Double Quotes
  • 125
  • 1
  • 2
  • 11