Luis Diaz
asked on
Windows batch: count files with /d and /s options
Hello experts,
I have the following batch which allows me to count files on specific folder:
I was wondering how to put:
-/d option to specify files with a date modified older than 30 days
-/s option to proceed recursively
If you have questions, please contact me.
Thank you for your help.
I have the following batch which allows me to count files on specific folder:
@echo off
setlocal enableextensions
set count=0
for %%x in ("C:\Temp") do set /a count+=1
echo Number of csv files: %count%
endlocal
pause
I was wondering how to put:
-/d option to specify files with a date modified older than 30 days
-/s option to proceed recursively
If you have questions, please contact me.
Thank you for your help.
ASKER
Thank you.
Possible to have /r option as flag parameter.
R=
No recursive to apply
R=Y
Recursive to apply
Possible to have /r option as flag parameter.
R=
No recursive to apply
R=Y
Recursive to apply
Your fastest and most effective method to do this is to leverage Robocopy.
Forfiles is slow and has some issues when working with date-times that Microsoft has never fixed.
For these reasosn, I usually do date comparisons of this sort using Robocopy.
When doing file counts DIR and Robocopy are much faster at returning a result than a loop is and in some cases, you can just use FIND to get exactly the info you want avoiding a loop entirely if you don't need to save the data for later.
I've amended your example script to utilize Robocopy and do either recursive or nonrecursive counts of files.
Forfiles is slow and has some issues when working with date-times that Microsoft has never fixed.
For these reasosn, I usually do date comparisons of this sort using Robocopy.
When doing file counts DIR and Robocopy are much faster at returning a result than a loop is and in some cases, you can just use FIND to get exactly the info you want avoiding a loop entirely if you don't need to save the data for later.
I've amended your example script to utilize Robocopy and do either recursive or nonrecursive counts of files.
@(
ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
SET "_FileCount="
SET "_CountPath=c:\Temp"
SET "_EmptyPath=c:\Empty"
SET "_FileGlob=*.csv"
SET "_MinAge=/MinAge:30"
SET "_Recurse=/S"
SET "_RoboCopyCMD=ROBOCOPY "!_CountPath!" "!_EmptyPath!" !_FileGlob! /L /NS /NC /NFL /NDL /NP /NJH !_Recurse! !_MinAge!"
)
FOR /F "Tokens=4" %%A IN ('%_RoboCopyCMD% ^| FIND /I "Files : "') DO (
SET "_FileCount=%%A"
ECHO.Files="%%A"
)
ECHO.Number of csv files: %_FileCount%
ENDLOCAL
PAUSE
Note, I had tprushout, if you want to remove recurse set it =" same with min age
If you want a pure BAT approach this should work:
»bp
@echo off
setlocal EnableDelayedExpansion
REM Define base for folders, and days to find newer files than
Set BaseDir=c:\temp
set DaysToFind=30
REM Get current date in MM/DD/YYYY format
set Today=
for /f "tokens=* skip=1" %%A in ('wmic os get LocalDateTime') do (
if not defined LocalDateTime (
set LocalDateTime=%%A
set Today=!LocalDateTime:~4,2!/!LocalDateTime:~6,2!/!LocalDateTime:~0,4!
)
)
REM Convert todays date to julian for age checks
call :jDate jToday %Today%
set count=0
REM Process all Files in the directory, count if newer than days specified
for /r "%BaseDir%" %%A in ("*.*") do (
call :jDate jFile %%~tA
set /A FileAge = !jToday! - !jFile!
if !FileAge! LEQ %DaysToFind% (
set /a count+=1
)
)
REM Display files found
echo Number of csv files: %count%
REM Done
exit /b
REM Subroutine to calculate julian date
:jDate [return-variable] [date-string(MM/DD/YYYY)]
set DateStr=%~2
set yy=%DateStr:~6,4%
set /A mm=1%DateStr:~0,2%-100
set /A dd=1%DateStr:~3,2%-100
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"
set /a %~1=dd-32075+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4
exit /b
»bp
ASKER
Thank you Ben for this proposal.
I have a little issue with this because I need to create C:\empty folder manually and then run the count.
Why not adding a mkdir withing the reference folder to loop and once it is finished rmdir?
Thank you for your help.
I have a little issue with this because I need to create C:\empty folder manually and then run the count.
Why not adding a mkdir withing the reference folder to loop and once it is finished rmdir?
Thank you for your help.
ASKER
Thank you Bill for this proposal.
I have the following error message:
I have the following error message:
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
@Louis, yes! I just didn't have time before Ieft, I had to rush out
Odd, I did test it here and didn't get any errors. You will probably need to run it with ECHO ON and then post up some of the lines that it displays before and after one of those error lines.
»bp
»bp
You could do this with Swiss File Knife too (much faster), but not sure if you ever embraced that tool (I think I mentioned it to you previously).
»bp
Sun 08/11/2019 13:28:28.45 C:\Temp>sfk list -juststat -since 90d -dir c:\temp *.*
24 files, 155 dirs, 131 kb, 131605 bytes.
skipped 19 hidden files, 0 hidden dirs.
»bp
ASKER
Agree, I have Swiss File Knife, however I need to perform this from an external VM and I want to avoid it installing.
Thank you for your help.
Thank you for your help.
@(
ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
SET "_FileCount="
SET "_CountPath=c:\Temp"
SET "_EmptyPath=c:\Empty"
IF NOT EXIST "!_EmptyPath!" (
MD "!_EmptyPath!"
)
SET "_FileGlob=*.csv"
SET "_MinAge=/MinAge:30"
SET "_Recurse=/S"
SET "_RoboCopyCMD=ROBOCOPY "!_CountPath!" "!_EmptyPath!" !_FileGlob! /L /NS /NC /NFL /NDL /NP /NJH !_Recurse! !_MinAge!"
)
FOR /F "Tokens=4" %%A IN ('%_RoboCopyCMD% ^| FIND /I "Files : "') DO (
SET "_FileCount=%%A"
ECHO.Files="%%A"
)
ECHO.Number of csv files: %_FileCount%
IF EXIST "!_EmptyPath!" (
RD /S /Q "!_EmptyPath!"
)
ENDLOCAL
PAUSE
ASKER
I tested and I had a big issue. My Count_Path was removed hopefully I did a backup before.
I prefer forfiles option as we don't create/remove any folder.
Anyway thank you for your help.
I prefer forfiles option as we don't create/remove any folder.
Anyway thank you for your help.
ASKER
@NVIT: possible to have:
1-Number of csv files in folder and subfolders (as is)
2-Number of csv files in folder (new)
3-Number of csv files in folder 30 or more days old (new)
4-Number of csv files in folder and subfolders 30 or more days old (as is)
Thank you for your help.
1-Number of csv files in folder and subfolders (as is)
2-Number of csv files in folder (new)
3-Number of csv files in folder 30 or more days old (new)
4-Number of csv files in folder and subfolders 30 or more days old (as is)
Thank you for your help.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you. Unable to test it right now. I will keep you informed.
ASKER
Thank you very much. It works!
Last question about this subject. If I want to set up dynamically /d to take into account the various files with a modified date after 01-08-2019 how should I proceed?
Last question about this subject. If I want to set up dynamically /d to take into account the various files with a modified date after 01-08-2019 how should I proceed?
Why does it have to be BAT when Powershell is quick, powerful and comes with Windows so nothing new to install?
Quick search gives several examples that can be easily tweaked:
https://social.technet.microsoft.com/Forums/en-US/a3d8d3f8-f37f-4022-9e11-2bbfca833f1a/checking-a-directory-for-files-older-than-5-minutes?forum=winserverpowershell
Quick search gives several examples that can be easily tweaked:
https://social.technet.microsoft.com/Forums/en-US/a3d8d3f8-f37f-4022-9e11-2bbfca833f1a/checking-a-directory-for-files-older-than-5-minutes?forum=winserverpowershell
> ... to set up dynamically /d ...
> ... to take into account the various files
> ... with a modified date after 01-08-2019
This request is unclear.
> ... to set up dynamically /d ...
Your original question states that /d refers to Date. Do you want the choice of different dates/days old, e.g. 1, 5, 10, 20, 30, 40, etc.?
> ... to take into account the various files
Do you want the choice of different filetype, instead of CSV?
> ... with a modified date after 01-08-2019
See first response in this post.
> ... to take into account the various files
> ... with a modified date after 01-08-2019
This request is unclear.
> ... to set up dynamically /d ...
Your original question states that /d refers to Date. Do you want the choice of different dates/days old, e.g. 1, 5, 10, 20, 30, 40, etc.?
> ... to take into account the various files
Do you want the choice of different filetype, instead of CSV?
> ... with a modified date after 01-08-2019
See first response in this post.
ASKER
Thank NVIT.
The last request was related to /d +01/8/2019
Your proposal support this parameter so all is ok. Thank you again for your support.
The last request was related to /d +01/8/2019
Your proposal support this parameter so all is ok. Thank you again for your support.
Open in new window